home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / gepackte_disketten / 1994 / 08_94_5.dms / 08_94_5.adf / term-4.0-Source.lha / termMain.c < prev    next >
C/C++ Source or Header  |  1994-07-14  |  89KB  |  4,769 lines

  1. /*
  2. **    termMain.c
  3. **
  4. **    Program main routines and event loop
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11. #include "termEmulationProcess.h"
  12.  
  13.     /* Argument vectors offsets. */
  14.  
  15. enum    {    ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
  16.         ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,
  17.  
  18.         ARG_COUNT
  19.     };
  20.  
  21.     /* Argument template. */
  22.  
  23. #define ARGTEMPLATE    "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S"
  24.  
  25.     /* Local config path variable. */
  26.  
  27. STATIC STRPTR        ConfigPath;
  28. STATIC UBYTE __far    ThePath[MAX_FILENAME_LENGTH];
  29.  
  30.     /* Local dialing list. */
  31.  
  32. STATIC struct List    *LocalDialList;
  33. STATIC LONG         LocalCount = -1;
  34.  
  35.     /* Startup file name. */
  36.  
  37. STATIC UBYTE __far    StartupFile[MAX_FILENAME_LENGTH];
  38.  
  39.     /* Segment split routine, has to be local. */
  40.  
  41. STATIC struct Process * __regargs    SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
  42. STATIC VOID                CloseLibs(VOID);
  43.  
  44.     /* main():
  45.      *
  46.      *    This is our main entry point, check for the right
  47.      *    Kickstart version and fire off the background task
  48.      *    if approritate.
  49.      */
  50.  
  51. LONG
  52. main()
  53. {
  54.     STRPTR Result;
  55.  
  56.         /* Are we running as a child of Workbench? */
  57.  
  58.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  59.  
  60.     if(!ThisProcess -> pr_CLI)
  61.     {
  62.         WaitPort(&ThisProcess -> pr_MsgPort);
  63.  
  64.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  65.     }
  66.     else
  67.         WBenchMsg = NULL;
  68.  
  69.         /* Now try to open dos.library and utility.library and go on examining
  70.          * our calling parameters.
  71.          */
  72.  
  73.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  74.     {
  75.         CloseLibs();
  76.  
  77.         return(RETURN_FAIL);
  78.     }
  79.  
  80.     if(!(UtilityBase = OpenLibrary("utility.library",0)))
  81.     {
  82.         CloseLibs();
  83.  
  84.         return(RETURN_FAIL);
  85.     }
  86.  
  87.         /* We were called from Shell. */
  88.  
  89.     if(ThisProcess -> pr_CLI)
  90.     {
  91.         STRPTR *ArgArray;
  92.  
  93.             /* Use the cute ReadArgs parser, allocate the
  94.              * argument vectors...
  95.              */
  96.  
  97.         if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  98.         {
  99.             struct RDArgs *ArgsPtr;
  100.  
  101.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  102.             {
  103.                 ArgsPtr -> RDA_ExtHelp =    "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
  104.                                 "            [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
  105.                                 "            [NEW] [SYNC] [QUIET] [BEHIND]\n\n"
  106.                                 "     Window = Output window specifier\n"
  107.                                 "  PubScreen = Name of public screen to open window upon\n"
  108.                                 "    Startup = ARexx script file to run on startup\n"
  109.                                 "   Settings = Main configuration file name or path name to search for it\n"
  110.                                 "       Unit = Serial device driver unit number\n"
  111.                                 "     Device = Serial device driver name\n"
  112.                                 "        New = Spawn a new `term' process\n"
  113.                                 "       Sync = Keep links to Shell environment\n"
  114.                                 "      Quiet = Start iconified\n"
  115.                                 "     Behind = Open screen behind all other screens, don't activate the window\n\n";
  116.  
  117.                     /* Parse the args (if any). */
  118.  
  119.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  120.                 {
  121.                         /* Pop a running `term' to the front? */
  122.  
  123.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
  124.                     {
  125.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  126.                         {
  127.                             if(TermPort -> TopWindow)
  128.                                 BumpWindow(TermPort -> TopWindow);
  129.                         }
  130.  
  131.                         TermPort = NULL;
  132.  
  133.                         FreeArgs(ArgsPtr);
  134.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  135.                         FreeVec(ArgArray);
  136.  
  137.                         CloseLibs();
  138.  
  139.                         return(RETURN_OK);
  140.                     }
  141.  
  142.                     if(ArgArray[ARG_DEBUG])
  143.                         DebugFlag = TRUE;
  144.  
  145.                         /* Are we to use a special settings path? */
  146.  
  147.                     if(ArgArray[ARG_SETTINGS])
  148.                     {
  149.                         ConfigPath = ThePath;
  150.  
  151.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  152.                     }
  153.  
  154.                         /* Are we to use a special ARexx host port name? */
  155.  
  156.                     if(ArgArray[ARG_PORTNAME])
  157.                         strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
  158.  
  159.                         /* Are we to use a special output window name? */
  160.  
  161.                     if(ArgArray[ARG_WINDOW])
  162.                         strcpy(WindowName,ArgArray[ARG_WINDOW]);
  163.  
  164.                         /* Are we to run an ARexx script on startup? */
  165.  
  166.                     if(ArgArray[ARG_STARTUP])
  167.                         strcpy(StartupFile,ArgArray[ARG_STARTUP]);
  168.  
  169.                         /* Are we to open a window on a public screen? */
  170.  
  171.                     if(ArgArray[ARG_PUBSCREEN])
  172.                         strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
  173.  
  174.                         /* Are we to use a special device? */
  175.  
  176.                     if(ArgArray[ARG_DEVICE])
  177.                     {
  178.                         strcpy(NewDevice,ArgArray[ARG_DEVICE]);
  179.  
  180.                         UseNewDevice = TRUE;
  181.                     }
  182.  
  183.                         /* Are we to use a special unit number? */
  184.  
  185.                     if(ArgArray[ARG_UNIT])
  186.                     {
  187.                         NewUnit = *(LONG *)ArgArray[ARG_UNIT];
  188.  
  189.                         UseNewUnit = TRUE;
  190.                     }
  191.  
  192.                         /* Are we to start up iconified? */
  193.  
  194.                     if(ArgArray[ARG_QUIET])
  195.                     {
  196.                         if(!StartupFile[0])
  197.                             DoIconify = TRUE;
  198.                     }
  199.  
  200.                         /* Hide the screen and don't activate the window? */
  201.  
  202.                     if(ArgArray[ARG_BEHIND])
  203.                         KeepQuiet = TRUE;
  204.  
  205.                         /* We are to keep our links to
  206.                          * the Shell.
  207.                          */
  208.  
  209.                     if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
  210.                     {
  211.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  212.  
  213.                             /* Do we have enough stack space available? */
  214.  
  215.                         if(((struct CommandLineInterface *)BADDR(ThisProcess -> pr_CLI)) -> cli_DefaultStack < 4096)
  216.                         {
  217.                             Printf("\33[1mterm:\33[0m %s.\a\n","Sorry, the Shell stack must be at least 16384 bytes large");
  218.  
  219.                             FreeArgs(ArgsPtr);
  220.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  221.                             FreeVec(ArgArray);
  222.  
  223.                             CloseLibs();
  224.  
  225.                             return(RETURN_FAIL);
  226.                         }
  227.  
  228.                             /* Open our resources and
  229.                              * squeak on failure.
  230.                              */
  231.  
  232.                         if(Result = OpenAll(ConfigPath))
  233.                         {
  234.                             if(Result[0])
  235.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  236.  
  237.                             FreeArgs(ArgsPtr);
  238.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  239.                             FreeVec(ArgArray);
  240.  
  241.                             CloseAll(TRUE);
  242.  
  243.                             return(RETURN_FAIL);
  244.                         }
  245.  
  246.                             /* Go into main input
  247.                              * loop.
  248.                              */
  249.  
  250.                         HandleInput();
  251.  
  252.                             /* Free the argument
  253.                              * data.
  254.                              */
  255.  
  256.                         FreeArgs(ArgsPtr);
  257.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  258.                         FreeVec(ArgArray);
  259.  
  260.                             /* Restore old priority. */
  261.  
  262.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  263.  
  264.                             /* Terminate execution. */
  265.  
  266.                         CloseAll(TRUE);
  267.  
  268.                         return(RETURN_OK);
  269.                     }
  270.  
  271.                     FreeArgs(ArgsPtr);
  272.                 }
  273.                 else
  274.                 {
  275.                     PrintFault(IoErr(),"term");
  276.  
  277.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  278.                     FreeVec(ArgArray);
  279.  
  280.                     CloseLibs();
  281.  
  282.                     return(RETURN_ERROR);
  283.                 }
  284.  
  285.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  286.             }
  287.  
  288.             FreeVec(ArgArray);
  289.  
  290.                 /* Create a new process from our code. */
  291.  
  292.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  293.             {
  294.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  295.  
  296.                 CloseLibs();
  297.  
  298.                 return(RETURN_FAIL);
  299.             }
  300.         }
  301.         else
  302.         {
  303.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  304.  
  305.             CloseLibs();
  306.  
  307.             return(RETURN_FAIL);
  308.         }
  309.     }
  310.     else
  311.     {
  312.         LONG StackSize;
  313.  
  314.         StackSize = (LONG)SysBase -> ThisTask -> tc_SPUpper - (LONG)SysBase -> ThisTask -> tc_SPLower;
  315.  
  316.         if(StackSize < 16384)
  317.         {
  318.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  319.                 MyEasyRequest(NULL,"`term' has a problem:\nThe current stack size of %ld bytes is too low,\nplease edit the tool icon to use at least\n16384 bytes and restart the program.","Continue",StackSize);
  320.  
  321.             CloseLibs();
  322.  
  323.             return(RETURN_FAIL);
  324.         }
  325.         else
  326.         {
  327.             WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  328.  
  329.                 /* Open icon.library, we want to take a
  330.                  * look at the icon.
  331.                  */
  332.  
  333.             if(IconBase = OpenLibrary("icon.library",0))
  334.             {
  335.                 struct DiskObject *Icon;
  336.  
  337.                     /* Try to read the icon file. */
  338.  
  339.                 if(Icon = GetProgramIcon())
  340.                 {
  341.                     STRPTR Type;
  342.  
  343.                     if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
  344.                         DebugFlag = TRUE;
  345.  
  346.                         /* Look for a `Settings' tooltype. */
  347.  
  348.                     if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  349.                     {
  350.                             /* Remember the path and continue. */
  351.  
  352.                         strcpy(ThePath,ConfigPath);
  353.  
  354.                         ConfigPath = ThePath;
  355.                     }
  356.  
  357.                         /* Look for a `Portname' tooltype. */
  358.  
  359.                     if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
  360.                         strcpy(RexxPortName,Type);
  361.                     else
  362.                         RexxPortName[0] = 0;
  363.  
  364.                         /* Look for a `Window' tooltype. */
  365.  
  366.                     if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
  367.                         strcpy(WindowName,Type);
  368.                     else
  369.                         WindowName[0] = 0;
  370.  
  371.                         /* Look for a `Pubscreen' tooltype. */
  372.  
  373.                     if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
  374.                         strcpy(SomePubScreenName,Type);
  375.                     else
  376.                         SomePubScreenName[0] = 0;
  377.  
  378.                         /* Look for a `Startup' tooltype. */
  379.  
  380.                     if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
  381.                         strcpy(StartupFile,Type);
  382.                     else
  383.                         StartupFile[0] = 0;
  384.  
  385.                         /* Look for a `Device' tooltype. */
  386.  
  387.                     if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
  388.                     {
  389.                         if(Type[0])
  390.                         {
  391.                             strcpy(NewDevice,Type);
  392.  
  393.                             UseNewDevice = TRUE;
  394.                         }
  395.                     }
  396.  
  397.                         /* Look for a `Unit' tooltype. */
  398.  
  399.                     if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
  400.                     {
  401.                         if(Type[0])
  402.                         {
  403.                             NewUnit = Atol(Type);
  404.  
  405.                             UseNewUnit = TRUE;
  406.                         }
  407.                     }
  408.  
  409.                         /* Look for a `Quiet' tooltype. */
  410.  
  411.                     if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
  412.                     {
  413.                         if(!StartupFile[0])
  414.                             DoIconify = TRUE;
  415.                     }
  416.  
  417.                         /* Look for a `Behind' tooltype. */
  418.  
  419.                     if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
  420.                         KeepQuiet = TRUE;
  421.  
  422.                         /* Free the icon. */
  423.  
  424.                     FreeDiskObject(Icon);
  425.                 }
  426.  
  427.                 CloseLibrary(IconBase);
  428.  
  429.                 IconBase = NULL;
  430.             }
  431.  
  432.                 /* Initialize this, so OpenAll will work with
  433.                  * correct data.
  434.                  */
  435.  
  436.             TermPort = (struct TermPort *)FindPort("term Port");
  437.  
  438.                 /* We were called from Workbench. */
  439.  
  440.             if(Result = OpenAll(ConfigPath))
  441.             {
  442.                 if(IntuitionBase && Result[0])
  443.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  444.  
  445.                 CloseAll(TRUE);
  446.             }
  447.             else
  448.                 HandleInput();
  449.         }
  450.     }
  451.  
  452.     return(RETURN_OK);
  453. }
  454.  
  455.     /* CloseLibs():
  456.      *
  457.      *    Plain and simple: close two libraries and clean up.
  458.      */
  459.  
  460. STATIC VOID
  461. CloseLibs(VOID)
  462. {
  463.     if(UtilityBase)
  464.     {
  465.         CloseLibrary(UtilityBase);
  466.  
  467.         UtilityBase = NULL;
  468.     }
  469.  
  470.     if(WBenchMsg)
  471.         CurrentDir(WBenchLock);
  472.  
  473.     if(DOSBase)
  474.     {
  475.         CloseLibrary(DOSBase);
  476.  
  477.         DOSBase = NULL;
  478.     }
  479.  
  480. #ifdef BETA
  481.     StopBetaTask();
  482. #endif    /* BETA */
  483.  
  484.     if(WBenchMsg)
  485.     {
  486.         Forbid();
  487.  
  488.         ReplyMsg((struct Message *)WBenchMsg);
  489.     }
  490. }
  491.  
  492.     /* ProcessCleanup(register __d1 BPTR SegList):
  493.      *
  494.      *    Frees all resource the main process has allocated when
  495.      *    it exits.
  496.      */
  497.  
  498. STATIC VOID __saveds __asm
  499. ProcessCleanup(register __d1 BPTR SegList)
  500. {
  501.     CloseAll(FALSE);
  502.  
  503.     Forbid();
  504.  
  505.     UnLoadSeg(SegList);
  506.  
  507.     CloseLibrary(DOSBase);
  508.  
  509.     DOSBase = NULL;
  510. }
  511.  
  512.     /* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
  513.      *
  514.      *    Create a new process from the current one.
  515.      */
  516.  
  517. STATIC struct Process * __regargs
  518. SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
  519. {
  520.     struct Process            *Child;
  521.     struct CommandLineInterface    *CLI;
  522.  
  523.     CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
  524.  
  525.     Forbid();
  526.  
  527.     Child = CreateNewProcTags(
  528.         NP_CommandName,    "term",
  529.         NP_Name,    Name,
  530.         NP_Priority,    Pri,
  531.         NP_StackSize,    StackSize,
  532.         NP_Entry,    Function,
  533.         NP_Cli,        TRUE,
  534.         NP_ExitCode,    ProcessCleanup,
  535.         NP_ExitData,    CLI -> cli_Module,
  536.     TAG_DONE);
  537.  
  538.     if(Child)
  539.         CLI -> cli_Module = NULL;
  540.  
  541.     Permit();
  542.  
  543.     return(Child);
  544. }
  545.  
  546.     /* HandleInput():
  547.      *
  548.      *    This is our main input loop (check window & serial).
  549.      */
  550.  
  551. VOID __saveds
  552. HandleInput()
  553. {
  554.     STRPTR    Error;
  555.     BOOLEAN    AlmostFinished = FALSE;
  556.  
  557.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  558.  
  559.         /* Open the resources we need. */
  560.  
  561.     if(!IntuitionBase)
  562.     {
  563.         STRPTR Result;
  564.  
  565.         if(Result = OpenAll(ConfigPath))
  566.         {
  567.             if(IntuitionBase && Result[0])
  568.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  569.  
  570.             if(WBenchMsg)
  571.                 CloseAll(TRUE);
  572.  
  573.             return;
  574.         }
  575.     }
  576.  
  577.     if(DoIconify)
  578.     {
  579.         HandleIconify();
  580.  
  581.         DoIconify = FALSE;
  582.  
  583.         if(MainTerminated)
  584.             goto Stop;
  585.     }
  586.  
  587. #ifndef BETA
  588.     if(!KeepQuiet)
  589.         BumpWindow(Window);
  590. #endif    /* BETA */
  591.  
  592.         /* Set up the public screen data. */
  593.  
  594.     PubScreenStuff();
  595.  
  596.         /* Change program priority. */
  597.  
  598.     SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
  599.  
  600.     BlockWindows();
  601.  
  602.         /* Load the phone book. */
  603.  
  604.     LoadPhonebook(LastPhone);
  605.  
  606.         /* Build new menu strip. */
  607.  
  608.     if(Error = BuildMenu())
  609.     {
  610.         if(IntuitionBase)
  611.             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  612.  
  613.         CloseAll(TRUE);
  614.  
  615.         return;
  616.     }
  617.  
  618. #ifdef BETA
  619.     StopBetaTask();
  620.  
  621.     if(!KeepQuiet)
  622.         BumpWindow(Window);
  623. #endif    /* BETA */
  624.  
  625.         /* Show our business card. */
  626.  
  627.     if(!StartupFile[0] && !KeepQuiet)
  628.     {
  629.         if(ShowAbout(TRUE))
  630.             while(HandleRexx());
  631.     }
  632.  
  633.     ReleaseWindows();
  634.  
  635.         /* Don't do anything silly. */
  636.  
  637.     KeepQuiet = FALSE;
  638.  
  639.         /* Initialize the modem. */
  640.  
  641.     SerialCommand(Config -> ModemConfig -> ModemInit);
  642.  
  643.         /* Execute the startup macro (if any). */
  644.  
  645.     if(Config -> CommandConfig -> StartupMacro[0])
  646.         SerialCommand(Config -> CommandConfig -> StartupMacro);
  647.  
  648.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  649.  
  650.         /* Go into input loop... */
  651.  
  652. Loop:    while(!MainTerminated)
  653.     {
  654.         if(Recording)
  655.         {
  656.             if(RecordingLine)
  657.                 Status = STATUS_RECORDING_LINE;
  658.             else
  659.                 Status = STATUS_RECORDING;
  660.         }
  661.  
  662.             /* Handle the signal responses. */
  663.  
  664.         HandleResponse();
  665.  
  666.         if(RebuildMenu)
  667.         {
  668.             if(Error = BuildMenu())
  669.             {
  670.                 if(IntuitionBase)
  671.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  672.  
  673.                 MainTerminated = TRUE;
  674.  
  675.                 break;
  676.             }
  677.  
  678.             RebuildMenu = FALSE;
  679.         }
  680.  
  681.             /* Are we to run an ARexx script file? */
  682.  
  683.         if(StartupFile[0])
  684.         {
  685.             BlockWindows();
  686.  
  687.             SendARexxCommand(StartupFile);
  688.  
  689.             ReleaseWindows();
  690.  
  691.             StartupFile[0] = 0;
  692.         }
  693.  
  694.             /* Are we to leave the main loop? */
  695.  
  696.         if(MainTerminated)
  697.             break;
  698.  
  699.             /* Make the user notice not too obvious events. */
  700.  
  701.         if(FlowInfo . Changed)
  702.             HandleFlowChange();
  703.  
  704.             /* Are we no longer online? */
  705.  
  706.         if(!Online && WasOnline)
  707.             HandleOnlineCleanup();
  708.  
  709.             /* Now for public screen mode changes. */
  710.  
  711.         if(FixPubScreenMode)
  712.             PubScreenStuff();
  713.  
  714.             /* Now for window size changes. */
  715.  
  716.         if(FixScreenSize)
  717.             ScreenSizeStuff();
  718.  
  719.             /* Somebody told us to re-open the display
  720.              * (changed the terminal emulation/colour
  721.              * mode, etc.).
  722.              */
  723.  
  724.         if(ResetDisplay)
  725.         {
  726.             if(!DisplayReset())
  727.                 break;
  728.         }
  729.  
  730.             /* Display the online cost. */
  731.  
  732.         if(!Online && CurrentPay)
  733.         {
  734.                 /* Reset the text rendering styles, font, etc. in
  735.                  * order to keep the following text from getting
  736.                  * illegible.
  737.                  */
  738.  
  739.             SoftReset();
  740.  
  741.                 /* Display how much we expect
  742.                  * the user will have to pay for
  743.                  * this call.
  744.                  */
  745.  
  746.             ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  747.  
  748.             CurrentPay = 0;
  749.         }
  750.  
  751.             /* Iconify the program? */
  752.  
  753.         if(DoIconify)
  754.         {
  755.             HandleIconify();
  756.  
  757.             if(MainTerminated)
  758.                 break;
  759.         }
  760.  
  761.             /* Reset the serial driver? */
  762.  
  763.         if(ResetSerial)
  764.         {
  765.             HandleSerialReset();
  766.  
  767.             if(MainTerminated)
  768.                 break;
  769.         }
  770.  
  771.             /* We are to release the serial.device (or
  772.              * whatever we are using) for some reason.
  773.              */
  774.  
  775.         if(ReleaseSerial)
  776.         {
  777.             HandleSerialRelease();
  778.  
  779.             if(MainTerminated)
  780.                 break;
  781.         }
  782.  
  783.             /* Invoke the dialing function? */
  784.  
  785.         if(DoDial != DIAL_IGNORE)
  786.         {
  787.             if(Online)
  788.             {
  789.                 FreeDialList(FALSE);
  790.  
  791.                 DoDial = DIAL_IGNORE;
  792.  
  793.                 Forbid();
  794.  
  795.                 if(DialMsg)
  796.                 {
  797.                     DialMsg -> rm_Result1 = RC_WARN;
  798.                     DialMsg -> rm_Result2 = 0;
  799.  
  800.                     ReplyMsg(DialMsg);
  801.  
  802.                     DialMsg = NULL;
  803.                 }
  804.  
  805.                 Permit();
  806.             }
  807.             else
  808.             {
  809.                 if(DoDial == DIAL_LIST)
  810.                 {
  811.                     BYTE OldStatus = Status;
  812.  
  813.                     DoDial = DIAL_IGNORE;
  814.  
  815.                     BlockWindows();
  816.  
  817.                     DialPanel();
  818.  
  819.                     FreeDialList(FALSE);
  820.  
  821.                     Status = OldStatus;
  822.  
  823.                     SetRedialMenu();
  824.  
  825.                     ReleaseWindows();
  826.                 }
  827.                 else
  828.                 {
  829.                     DoDial = DIAL_IGNORE;
  830.  
  831.                     HandleMenuCode(MEN_REDIAL,NULL);
  832.                 }
  833.             }
  834.         }
  835.  
  836.             /* Can we quit now? */
  837.  
  838.         if(AlmostFinished && !CantQuit)
  839.             break;
  840.     }
  841.  
  842.         /* Don't exit until all background processes
  843.          * have terminated.
  844.          */
  845.  
  846.     if(MainTerminated && CantQuit)
  847.     {
  848.         MainTerminated = FALSE;
  849.         AlmostFinished = TRUE;
  850.  
  851.         goto Loop;
  852.     }
  853.  
  854.     AlmostFinished = FALSE;
  855.  
  856.         /* User wants to quit term, so let's try to close
  857.          * our magnificient screen and exit.
  858.          */
  859.  
  860. Stop:    if(Screen)
  861.     {
  862.         struct List        *PubScreenList;
  863.         struct PubScreenNode    *ScreenNode;
  864.  
  865.             /* Lock the list of public screens. */
  866.  
  867.         PubScreenList = LockPubScreenList();
  868.  
  869.             /* Scan the list and try to find our
  870.              * private node.
  871.              */
  872.  
  873.         for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
  874.         {
  875.             if(ScreenNode -> psn_Screen == Screen)
  876.                 break;
  877.         }
  878.  
  879.         if(ScreenNode)
  880.         {
  881.                 /* Okay, we know who and where we are,
  882.                  * check the number of visitor windows
  883.                  * currently open on our screen.
  884.                  */
  885.  
  886.             if(ScreenNode -> psn_VisitorCount)
  887.             {
  888.                     /* No chance, don't close
  889.                      * the screen now.
  890.                      */
  891.  
  892.                 UnlockPubScreenList();
  893.  
  894.                 BlockWindows();
  895.  
  896.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  897.  
  898.                 ReleaseWindows();
  899.  
  900.                 AlmostFinished = MainTerminated = FALSE;
  901.  
  902.                 goto Loop;
  903.             }
  904.         }
  905.  
  906.         UnlockPubScreenList();
  907.     }
  908.  
  909.         /* Send the modem exit command, shut down the
  910.          * serial.device and close all resources.
  911.          */
  912.  
  913.     SerialCommand(Config -> ModemConfig -> ModemExit);
  914.  
  915.     ClearSerial();
  916.  
  917.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  918.  
  919.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  920.  
  921.     if(Phonebook && PhoneSize)
  922.         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  923.  
  924.     if(!ThisProcess -> pr_CLI)
  925.         CloseAll(TRUE);
  926. }
  927.  
  928.     /* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell):
  929.      *
  930.      *    Transmit text the user typed or pasted via the
  931.      *    clipboard.
  932.      */
  933.  
  934. STATIC VOID __regargs
  935. SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell)
  936. {
  937.     UBYTE Mask,c;
  938.  
  939.     if(Config -> SerialConfig -> StripBit8)
  940.         Mask = 0x7F;
  941.     else
  942.         Mask = 0xFF;
  943.  
  944.     while(Len--)
  945.     {
  946.         switch(CharType[c = (*Buffer++) & Mask])
  947.         {
  948.             case CHAR_ENTER:
  949.  
  950.                 if(Status == STATUS_HOLDING)
  951.                 {
  952.                     if(Bell)
  953.                         BellSignal();
  954.                 }
  955.                 else
  956.                 {
  957.                     switch(Config -> TerminalConfig -> SendLF)
  958.                     {
  959.                         case LF_ASLF:
  960.  
  961.                             SerWrite("\n",1);
  962.                             break;
  963.  
  964.                         case LF_ASLFCR:
  965.  
  966.                             SerWrite("\n\r",2);
  967.                             break;
  968.                     }
  969.                 }
  970.  
  971.                 break;
  972.  
  973.             case CHAR_RETURN:
  974.  
  975.                 if(Status == STATUS_HOLDING)
  976.                 {
  977.                     if(Bell)
  978.                         BellSignal();
  979.                 }
  980.                 else
  981.                 {
  982.                     switch(Config -> TerminalConfig -> SendCR)
  983.                     {
  984.                         case CR_ASCR:
  985.  
  986.                             SerWrite("\r",1);
  987.                             break;
  988.  
  989.                         case CR_ASCRLF:
  990.  
  991.                             SerWrite("\r\n",2);
  992.                             break;
  993.                     }
  994.                 }
  995.  
  996.                 break;
  997.  
  998.                 /* Stop in/output. */
  999.  
  1000.             case CHAR_XON:
  1001.  
  1002.                 if(Status == STATUS_HOLDING)
  1003.                 {
  1004.                     if(Bell)
  1005.                         BellSignal();
  1006.                 }
  1007.                 else
  1008.                 {
  1009.                     if(Config -> SerialConfig -> xONxOFF)
  1010.                         Status = STATUS_HOLDING;
  1011.  
  1012.                     if(Config -> SerialConfig -> PassThrough)
  1013.                         SerWrite(&c,1);
  1014.                 }
  1015.  
  1016.                 break;
  1017.  
  1018.                 /* Restart in/output. */
  1019.  
  1020.             case CHAR_XOFF:
  1021.  
  1022.                 if(Status == STATUS_HOLDING)
  1023.                     Status = STATUS_READY;
  1024.  
  1025.                 if(Config -> SerialConfig -> PassThrough)
  1026.                     SerWrite(&c,1);
  1027.  
  1028.                 break;
  1029.  
  1030.                 /* Any other character. */
  1031.  
  1032.             case CHAR_VANILLA:
  1033.  
  1034.                 if(Status == STATUS_HOLDING)
  1035.                 {
  1036.                     if(Bell)
  1037.                         BellSignal();
  1038.                 }
  1039.                 else
  1040.                 {
  1041.                     if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1042.                     {
  1043.                             /* Convert special
  1044.                              * Amiga characters into
  1045.                              * alien IBM dialect.
  1046.                              */
  1047.  
  1048.                         if(IBMConversion[c])
  1049.                             SerWrite(&IBMConversion[c],1);
  1050.                         else
  1051.                             SerWrite(&c,1);
  1052.                     }
  1053.                     else
  1054.                         SerWrite(&c,1);
  1055.                 }
  1056.  
  1057.                 break;
  1058.         }
  1059.     }
  1060. }
  1061.  
  1062.     /* HandleWindow():
  1063.      *
  1064.      *    This funny part checks the window(s) for incoming
  1065.      *    user input. Menus are handled elsewhere.
  1066.      */
  1067.  
  1068. BYTE
  1069. HandleWindow()
  1070. {
  1071.     STATIC ULONG         LastSeconds,LastMicros;
  1072.  
  1073.     struct IntuiMessage    *Message;
  1074.     ULONG             IClass,Code,Qualifier,Seconds,Micros;
  1075.     LONG             MouseX,MouseY,Len,GadgetID;
  1076.     struct Gadget        *Gadget;
  1077.     UBYTE             Char,InputBuffer[257];
  1078.     struct Window        *IDCMPWindow;
  1079.     BOOLEAN             Result = FALSE,ClickAndActivate = FALSE;
  1080.  
  1081.         /* Are we reading input from the clipboard? */
  1082.  
  1083.     if(ClipInput)
  1084.     {
  1085.         WORD Len = GetClip(InputBuffer,256,FALSE);
  1086.  
  1087.         if(Len < 0)
  1088.         {
  1089.             CloseClip();
  1090.  
  1091.             ClipInput = FALSE;
  1092.  
  1093.             if(ClipXerox)
  1094.             {
  1095.                 if(Config -> ClipConfig -> InsertSuffix[0])
  1096.                     SerialCommand(Config -> ClipConfig -> InsertSuffix);
  1097.  
  1098.                 ClipXerox = FALSE;
  1099.             }
  1100.  
  1101.             ClipPrefix = FALSE;
  1102.         }
  1103.         else
  1104.         {
  1105.             if(!ClipPrefix && ClipXerox)
  1106.             {
  1107.                 if(Config -> ClipConfig -> InsertPrefix[0])
  1108.                     SerialCommand(Config -> ClipConfig -> InsertPrefix);
  1109.  
  1110.                 ClipPrefix = TRUE;
  1111.             }
  1112.  
  1113.             if(Len > 0)
  1114.                 SendInputTextBuffer(InputBuffer,Len,FALSE);
  1115.  
  1116.             Result = TRUE;
  1117.         }
  1118.     }
  1119.  
  1120.         /* Any news in the mail? */
  1121.  
  1122.     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  1123.     {
  1124.             /* A click into the window should activate it, but
  1125.              * we don't want to have the character snapping activated
  1126.              * under these conditions. In this case we rely upon
  1127.              * Intuition sending the IDCMP_ACTIVEWINDOW and
  1128.              * IDCMP_MOUSEBUTTONS event marked with the same
  1129.              * creation time stamp. Even if the Intuition
  1130.              * implementation should change no harm should
  1131.              * be done.
  1132.              */
  1133.  
  1134.         Seconds    = Message -> Seconds;
  1135.         Micros    = Message -> Micros;
  1136.  
  1137.         if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
  1138.         {
  1139.             if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
  1140.                 ClickAndActivate = TRUE;
  1141.         }
  1142.  
  1143.         LastSeconds    = Seconds;
  1144.         LastMicros    = Micros;
  1145.  
  1146.             /* Pick up the pieces. */
  1147.  
  1148.         IClass        = Message -> Class;
  1149.         Code        = Message -> Code;
  1150.         Qualifier    = Message -> Qualifier;
  1151.         Gadget        = (struct Gadget *)Message -> IAddress;
  1152.  
  1153.         MouseX        = Message -> MouseX;
  1154.         MouseY        = Message -> MouseY;
  1155.  
  1156.         IDCMPWindow    = Message -> IDCMPWindow;
  1157.  
  1158.         if(IClass == IDCMP_IDCMPUPDATE)
  1159.             GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
  1160.  
  1161.         if(IClass == IDCMP_RAWKEY)
  1162.         {
  1163.                 /* Perform key conversion. */
  1164.  
  1165.             if(XEmulatorBase)
  1166.             {
  1167.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
  1168.                     Char = InputBuffer[0];
  1169.             }
  1170.             else
  1171.                 Char = KeyConvert(Message,InputBuffer,&Len);
  1172.         }
  1173.  
  1174.         ReplyMsg(Message);
  1175.     }
  1176.     else
  1177.         IClass = NULL;
  1178.  
  1179.         /* Did we get any information? */
  1180.  
  1181.     if(IClass)
  1182.     {
  1183.             /* The following messages probably
  1184.              * originated from the fast! macro
  1185.              * panel.
  1186.              */
  1187.  
  1188.         if(IDCMPWindow == FastWindow)
  1189.         {
  1190.             switch(IClass)
  1191.             {
  1192.                     /* Close the window. */
  1193.  
  1194.                 case IDCMP_CLOSEWINDOW:
  1195.  
  1196.                     CloseFastWindow();
  1197.  
  1198.                     return(TRUE);
  1199.  
  1200.                     /* Window size has changed for some reason. */
  1201.  
  1202.                 case IDCMP_NEWSIZE:
  1203.  
  1204.                     RefreshFastWindow(FALSE);
  1205.  
  1206.                     return(TRUE);
  1207.  
  1208.                     /* Some gadget was invoked. */
  1209.  
  1210.                 case IDCMP_GADGETUP:
  1211.                 case IDCMP_GADGETDOWN:
  1212.  
  1213.                     GadgetID = Gadget -> GadgetID;
  1214.  
  1215.                 case IDCMP_MOUSEMOVE:
  1216.                 case IDCMP_IDCMPUPDATE:
  1217.  
  1218.                     HandleFastWindowGadget(IClass,Code,GadgetID);
  1219.  
  1220.                     return(TRUE);
  1221.             }
  1222.         }
  1223.  
  1224.             /* Status window activated? */
  1225.  
  1226.         if(IDCMPWindow == StatusWindow)
  1227.         {
  1228.             if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
  1229.                 NormalCursor();
  1230.  
  1231.             if(IClass == IDCMP_CLOSEWINDOW)
  1232.             {
  1233.                 Forbid();
  1234.  
  1235.                 ClrSignal(SIG_HANDSHAKE);
  1236.  
  1237.                 Signal(StatusProcess,SIG_CLOSEWINDOW);
  1238.  
  1239.                 Wait(SIG_HANDSHAKE);
  1240.  
  1241.                 Permit();
  1242.  
  1243.                 ClearMenuStrip(StatusWindow);
  1244.                 CloseWindowSafely(StatusWindow);
  1245.  
  1246.                 StatusWindow = NULL;
  1247.             }
  1248.         }
  1249.  
  1250.             /* Main window message? */
  1251.  
  1252.         if(IDCMPWindow == Window)
  1253.         {
  1254.             switch(IClass)
  1255.             {
  1256.                 case IDCMP_INACTIVEWINDOW:
  1257.  
  1258.                     HoldClick = FALSE;
  1259.  
  1260.                     GhostCursor();
  1261.  
  1262.                     break;
  1263.  
  1264.                 case IDCMP_ACTIVEWINDOW:
  1265.  
  1266.                     NormalCursor();
  1267.  
  1268.                     break;
  1269.  
  1270.                 case IDCMP_NEWSIZE:
  1271.  
  1272.                         /* Is a window clipping region installed? */
  1273.  
  1274.                     if(ClipRegion)
  1275.                     {
  1276.                         struct Rectangle RegionRectangle;
  1277.  
  1278.                             /* Install old region. */
  1279.  
  1280.                         InstallClipRegion(Window -> WLayer,OldRegion);
  1281.  
  1282.                             /* Fill in the clipping rectangle. */
  1283.  
  1284.                         RegionRectangle . MinX = Window -> BorderLeft;
  1285.                         RegionRectangle . MinY = Window -> BorderTop;
  1286.                         RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
  1287.                         RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
  1288.  
  1289.                             /* Clear previous clipping region. */
  1290.  
  1291.                         ClearRegion(ClipRegion);
  1292.  
  1293.                             /* Set new clipping region. */
  1294.  
  1295.                         OrRectRegion(ClipRegion,&RegionRectangle);
  1296.  
  1297.                             /* Install new clipping region. */
  1298.  
  1299.                         OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
  1300.                     }
  1301.  
  1302.                     HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
  1303.                     break;
  1304.  
  1305.                 case IDCMP_CLOSEWINDOW:
  1306.  
  1307.                     HandleMenuCode(MEN_QUIT,Qualifier);
  1308.                     break;
  1309.  
  1310.                 case IDCMP_MOUSEMOVE:
  1311.  
  1312.                     if(HoldClick)
  1313.                     {
  1314.                         if(!Marking)
  1315.                             SetMarker(ClickX,ClickY);
  1316.                         else
  1317.                         {
  1318.                             MouseX -= WindowLeft;
  1319.  
  1320.                             if(MouseX < 0)
  1321.                                 MouseX = 0;
  1322.  
  1323.                             if(MouseX > WindowWidth - 1)
  1324.                                 MouseX = WindowWidth - 1;
  1325.  
  1326.                             MouseY -= WindowTop;
  1327.  
  1328.                             if(MouseY < 0)
  1329.                                 MouseY = 0;
  1330.  
  1331.                             if(MouseY > WindowHeight - 1)
  1332.                                 MouseY = WindowHeight - 1;
  1333.  
  1334.                             MoveMarker(MouseX,MouseY);
  1335.                         }
  1336.                     }
  1337.  
  1338.                     break;
  1339.  
  1340.                 case IDCMP_MOUSEBUTTONS:
  1341.  
  1342.                     if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
  1343.                     {
  1344.                         if(Code == SELECTUP)
  1345.                             HoldClick = FALSE;
  1346.  
  1347.                         if(Code == SELECTDOWN)
  1348.                         {
  1349.                             MouseX -= WindowLeft;
  1350.  
  1351.                             if(MouseX < 0)
  1352.                                 MouseX = 0;
  1353.  
  1354.                             if(MouseX > WindowWidth - 1)
  1355.                                 MouseX = WindowWidth - 1;
  1356.  
  1357.                             MouseY -= WindowTop;
  1358.  
  1359.                             if(MouseY < 0)
  1360.                                 MouseY = 0;
  1361.  
  1362.                             if(MouseY > WindowHeight - 1)
  1363.                                 MouseY = WindowHeight - 1;
  1364.  
  1365.                             HoldClick = TRUE;
  1366.  
  1367.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1368.                             {
  1369.                                 WORD FirstX,FirstY;
  1370.  
  1371.                                 FirstX = MouseX / TextFontWidth;
  1372.                                 FirstY = MouseY / TextFontHeight;
  1373.  
  1374.                                 if(FirstX <= LastColumn && FirstY <= LastLine)
  1375.                                 {
  1376.                                     UBYTE Char;
  1377.  
  1378.                                     ObtainSemaphore(RasterSemaphore);
  1379.  
  1380.                                     Char = Raster[FirstY * RasterWidth + FirstX];
  1381.  
  1382.                                     ReleaseSemaphore(RasterSemaphore);
  1383.  
  1384.                                     if(Char)
  1385.                                     {
  1386.                                         SerWrite(&Char,1);
  1387.  
  1388.                                         if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1389.                                         {
  1390.                                             switch(Config -> TerminalConfig -> SendCR)
  1391.                                             {
  1392.                                                 case CR_ASCR:
  1393.  
  1394.                                                     SerWrite("\r",1);
  1395.                                                     break;
  1396.  
  1397.                                                 case CR_ASCRLF:
  1398.  
  1399.                                                     SerWrite("\r\n",2);
  1400.                                                     break;
  1401.                                             }
  1402.                                         }
  1403.                                     }
  1404.                                 }
  1405.  
  1406.                                 return(TRUE);
  1407.                             }
  1408.  
  1409.                             if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1410.                             {
  1411.                                 WORD DeltaX,DeltaY;
  1412.  
  1413.                                 ObtainTerminal();
  1414.  
  1415.                                 DeltaX = MouseX / TextFontWidth  - CursorX;
  1416.                                 DeltaY = MouseY / TextFontHeight - CursorY;
  1417.  
  1418.                                 ReleaseTerminal();
  1419.  
  1420.                                 if(DeltaX || DeltaY)
  1421.                                 {
  1422.                                     if(DeltaX > 0)
  1423.                                     {
  1424.                                         DeltaX++;
  1425.  
  1426.                                         while(DeltaX--)
  1427.                                             SerWrite("\33[C",3);
  1428.                                     }
  1429.  
  1430.                                     if(DeltaX < 0)
  1431.                                     {
  1432.                                         while(DeltaX++)
  1433.                                             SerWrite("\33[D",3);
  1434.                                     }
  1435.  
  1436.                                     if(DeltaY > 0)
  1437.                                     {
  1438.                                         DeltaY++;
  1439.  
  1440.                                         while(DeltaY--)
  1441.                                             SerWrite("\33[B",3);
  1442.                                     }
  1443.  
  1444.                                     if(DeltaY < 0)
  1445.                                     {
  1446.                                         while(DeltaY++)
  1447.                                             SerWrite("\33[A",3);
  1448.                                     }
  1449.                                 }
  1450.  
  1451.                                 return(TRUE);
  1452.                             }
  1453.  
  1454.                             ReportMouse(TRUE,Window);
  1455.  
  1456.                             if(!FirstClick)
  1457.                             {
  1458.                                 ULONG CurrentSecs,CurrentMicros;
  1459.  
  1460.                                 CurrentTime(&CurrentSecs,&CurrentMicros);
  1461.  
  1462.                                 FirstClick = TRUE;
  1463.  
  1464.                                 if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
  1465.                                 {
  1466.                                     MarkWord(ClickX,ClickY);
  1467.  
  1468.                                     return(TRUE);
  1469.                                 }
  1470.                                 else
  1471.                                 {
  1472.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1473.  
  1474.                                     FirstClick    = FALSE;
  1475.  
  1476.                                     ClickX        = MouseX;
  1477.                                     ClickY        = MouseY;
  1478.                                 }
  1479.                             }
  1480.                             else
  1481.                             {
  1482.                                 CurrentTime(&ClickSecs,&ClickMicros);
  1483.  
  1484.                                 FirstClick    = FALSE;
  1485.  
  1486.                                 ClickX        = MouseX;
  1487.                                 ClickY        = MouseY;
  1488.                             }
  1489.  
  1490.                             if(Marking)
  1491.                             {
  1492.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1493.                                     MoveMarker(MouseX,MouseY);
  1494.                                 else
  1495.                                 {
  1496.                                     DropMarker();
  1497.  
  1498.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1499.  
  1500.                                     FirstClick    = FALSE;
  1501.  
  1502.                                     ClickX        = MouseX;
  1503.                                     ClickY        = MouseY;
  1504.  
  1505.                                     ReportMouse(TRUE,Window);
  1506.                                 }
  1507.                             }
  1508.                         }
  1509.                     }
  1510.  
  1511.                     break;
  1512.             }
  1513.         }
  1514.  
  1515.             /* Now for general information. */
  1516.  
  1517.         switch(IClass)
  1518.         {
  1519.             case IDCMP_RAWKEY:
  1520.  
  1521.                     /* This looks like a raw, or better, now cooked key. */
  1522.  
  1523.                 if(Len)
  1524.                 {
  1525.                     switch(CharType[Char])
  1526.                     {
  1527.                         case CHAR_HELP:
  1528.  
  1529.                             GuideDisplay(CONTEXT_MAIN);
  1530.  
  1531.                             Len = 0;
  1532.  
  1533.                             break;
  1534.  
  1535.                         case CHAR_CURSOR:
  1536.  
  1537.                             if(ClipInput)
  1538.                             {
  1539.                                 CloseClip();
  1540.  
  1541.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1542.                             }
  1543.  
  1544.                                 /* If in cursor key applications mode,
  1545.                                  * send the corresponding string.
  1546.                                  */
  1547.  
  1548.                             if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
  1549.                             {
  1550.                                 STATIC STRPTR CursorTable[4] =
  1551.                                 {
  1552.                                     "\033OA",
  1553.                                     "\033OB",
  1554.                                     "\033OC",
  1555.                                     "\033OD"
  1556.                                 };
  1557.  
  1558.                                 SerWrite(CursorTable[Char - CUP],3);
  1559.                             }
  1560.                             else
  1561.                             {
  1562.                                 WORD QualType;
  1563.  
  1564.                                     /* Find the approriate qualifier. */
  1565.  
  1566.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1567.                                     QualType = 1;
  1568.                                 else
  1569.                                 {
  1570.                                     if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1571.                                         QualType = 2;
  1572.                                     else
  1573.                                     {
  1574.                                         if(Qualifier & IEQUALIFIER_CONTROL)
  1575.                                             QualType = 3;
  1576.                                         else
  1577.                                             QualType = 0;
  1578.                                     }
  1579.                                 }
  1580.  
  1581.                                     /* Send the corresponding string. */
  1582.  
  1583.                                 SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
  1584.                             }
  1585.  
  1586.                             Len = 0;
  1587.  
  1588.                             break;
  1589.  
  1590.                             /* Any function key pressed? */
  1591.  
  1592.                         case CHAR_FUNCTION:
  1593.  
  1594.                             if(ClipInput)
  1595.                             {
  1596.                                 CloseClip();
  1597.  
  1598.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1599.                             }
  1600.  
  1601.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1602.                                 SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  1603.                             else
  1604.                             {
  1605.                                 if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1606.                                     SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  1607.                                 else
  1608.                                 {
  1609.                                     if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1610.                                         SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  1611.                                     else
  1612.                                         SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  1613.                                 }
  1614.                             }
  1615.  
  1616.                             Len = 0;
  1617.  
  1618.                             break;
  1619.  
  1620.                             /* Anything else? */
  1621.  
  1622.                         default:
  1623.  
  1624.                             if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  1625.                             {
  1626.                                 RememberInputText("\r",1);
  1627.  
  1628.                                 Len = 0;
  1629.  
  1630.                                 RecordingLine = TRUE;
  1631.  
  1632.                                 RememberResetInput();
  1633.  
  1634.                                 RememberOutput = FALSE;
  1635.                                 RememberInput = TRUE;
  1636.  
  1637.                                 CheckItem(MEN_RECORD_LINE,TRUE);
  1638.                             }
  1639.  
  1640.                             if(Len == 1 && (Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
  1641.                             {
  1642.                                 STATIC STRPTR ApplicationTable[20][2] =
  1643.                                 {
  1644.                                     "0",    "\033Op",
  1645.                                     "1",    "\033Oq",
  1646.                                     "2",    "\033Or",
  1647.                                     "3",    "\033Os",
  1648.                                     "4",    "\033Ot",
  1649.                                     "5",    "\033Ou",
  1650.                                     "6",    "\033Ov",
  1651.                                     "7",    "\033Ow",
  1652.                                     "8",    "\033Ox",
  1653.                                     "9",    "\033Oy",
  1654.                                     "-",    "\033Om",
  1655.                                     "+",    "\033Ol",    /* This should really be a comma */
  1656.                                     ".",    "\033On",
  1657.  
  1658.                                     "[",    "\033OP",
  1659.                                     "{",    "\033OP",
  1660.                                     "]",    "\033OQ",
  1661.                                     "}",    "\033OQ",
  1662.                                     "/",    "\033OR",
  1663.                                     "*",    "\033OS",
  1664.  
  1665.                                     "\r",    "\033OM"
  1666.                                 };
  1667.  
  1668.                                 WORD i;
  1669.  
  1670.                                 for(i = 0 ; i < 20 ; i++)
  1671.                                 {
  1672.                                     if(Char == ApplicationTable[i][0][0])
  1673.                                     {
  1674.                                         if(ClipInput)
  1675.                                         {
  1676.                                             CloseClip();
  1677.  
  1678.                                             ClipInput = ClipXerox = ClipPrefix = FALSE;
  1679.                                         }
  1680.  
  1681.                                         SerWrite(ApplicationTable[i][1],strlen(ApplicationTable[i][1]));
  1682.  
  1683.                                         Len = 0;
  1684.  
  1685.                                         break;
  1686.                                     }
  1687.                                 }
  1688.                             }
  1689.  
  1690.                             break;
  1691.                     }
  1692.  
  1693.                         /* Any characters to send? */
  1694.  
  1695.                     if(Len)
  1696.                         SendInputTextBuffer(InputBuffer,Len,TRUE);
  1697.                 }
  1698.  
  1699.                 break;
  1700.  
  1701.                 /* A menu item was selected. */
  1702.  
  1703.             case IDCMP_MENUPICK:
  1704.  
  1705.                 HandleMenu(Code,Qualifier);
  1706.                 break;
  1707.         }
  1708.  
  1709.         return(TRUE);
  1710.     }
  1711.  
  1712.     return(Result);
  1713. }
  1714.  
  1715.     /* HandleLocalDialList(BYTE ClearIt):
  1716.      *
  1717.      *    Invoke the local dialing list or clear it.
  1718.      */
  1719.  
  1720. STATIC VOID __regargs
  1721. HandleLocalDialList(BYTE ClearIt)
  1722. {
  1723.     if(Menu)
  1724.     {
  1725.         struct MenuItem *DialItem;
  1726.  
  1727.         if(DialItem = FindThisItem(Menu,FirstDialMenu))
  1728.         {
  1729.             if(Window)
  1730.                 ClearMenuStrip(Window);
  1731.  
  1732.             if(StatusWindow)
  1733.                 ClearMenuStrip(StatusWindow);
  1734.  
  1735.             if(FastWindow)
  1736.                 ClearMenuStrip(FastWindow);
  1737.  
  1738.             do
  1739.                 DialItem -> Flags &= ~CHECKED;
  1740.             while(DialItem = DialItem -> NextItem);
  1741.  
  1742.             if(Window)
  1743.                 ResetMenuStrip(Window,Menu);
  1744.  
  1745.             if(StatusWindow)
  1746.                 ResetMenuStrip(StatusWindow,Menu);
  1747.  
  1748.             if(FastWindow)
  1749.                 ResetMenuStrip(FastWindow,Menu);
  1750.         }
  1751.     }
  1752.  
  1753.     if(LocalDialList)
  1754.     {
  1755.         if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
  1756.         {
  1757.             FreeDialList(TRUE);
  1758.  
  1759.             DialList = LocalDialList;
  1760.  
  1761.             LocalDialList = NULL;
  1762.  
  1763.             LocalCount = -1;
  1764.  
  1765.             SetRedialMenu();
  1766.  
  1767.             HandleMenuCode(MEN_REDIAL,NULL);
  1768.         }
  1769.         else
  1770.         {
  1771.             FreeList(LocalDialList);
  1772.  
  1773.             FreeVecPooled(LocalDialList);
  1774.  
  1775.             LocalDialList = NULL;
  1776.  
  1777.             LocalCount = -1;
  1778.         }
  1779.     }
  1780. }
  1781.  
  1782.     /* HandleMenuCode(ULONG Code,ULONG Qualifier):
  1783.      *
  1784.      *    Handle each function associated with a menu code.
  1785.      */
  1786.  
  1787. VOID __regargs
  1788. HandleMenuCode(ULONG Code,ULONG Qualifier)
  1789. {
  1790.     struct FileRequester    *FileRequest;
  1791.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  1792.                 *DummyChar;
  1793.     BYTE             OldStatus = Status;
  1794.  
  1795.     BPTR             SomeFile;
  1796.     APTR             OldPtr;
  1797.  
  1798.     struct MenuItem        *Item;
  1799.  
  1800.     switch(Code)
  1801.     {
  1802.             /* Save screen as IFF-ILBM file. */
  1803.  
  1804.         case MEN_SAVE_AS_PICTURE:
  1805.  
  1806.             BlockWindows();
  1807.  
  1808.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
  1809.             {
  1810.                 if(!SaveWindow(DummyBuffer,Window))
  1811.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  1812.  
  1813.                 FreeAslRequest(FileRequest);
  1814.             }
  1815.  
  1816.             ReleaseWindows();
  1817.  
  1818.             break;
  1819.  
  1820.             /* Save screen as ASCII file. */
  1821.  
  1822.         case MEN_SAVE_AS_TEXT:
  1823.  
  1824.             BlockWindows();
  1825.  
  1826.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  1827.             {
  1828.                 LONG Error = 0;
  1829.  
  1830.                 if(GetFileSize(DummyBuffer))
  1831.                 {
  1832.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  1833.                     {
  1834.                         case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1835.                             break;
  1836.  
  1837.                         case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  1838.                             {
  1839.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  1840.                                 {
  1841.                                     Close(SomeFile);
  1842.  
  1843.                                     SomeFile = NULL;
  1844.                                 }
  1845.                             }
  1846.  
  1847.                             break;
  1848.  
  1849.                         case 0:    SomeFile = ~0;
  1850.                             break;
  1851.                     }
  1852.                 }
  1853.                 else
  1854.                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1855.  
  1856.                 if(SomeFile)
  1857.                 {
  1858.                     if(SomeFile != ~0)
  1859.                     {
  1860.                         LONG     i,j;
  1861.                         UBYTE    *Buffer;
  1862.  
  1863.                         for(i = 0 ; i < RasterHeight ; i++)
  1864.                         {
  1865.                             Buffer = &Raster[i * RasterWidth];
  1866.  
  1867.                             j = LastColumn;
  1868.  
  1869.                             while(j >= 0 && Buffer[j] == ' ')
  1870.                                 j--;
  1871.  
  1872.                             if(j >= 0)
  1873.                             {
  1874.                                 SetIoErr(0);
  1875.  
  1876.                                 if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
  1877.                                 {
  1878.                                     Error = IoErr();
  1879.  
  1880.                                     break;
  1881.                                 }
  1882.                             }
  1883.  
  1884.                             SetIoErr(0);
  1885.  
  1886.                             if(FWrite(SomeFile,"\n",1,1) < 1)
  1887.                             {
  1888.                                 Error = IoErr();
  1889.  
  1890.                                 break;
  1891.                             }
  1892.                         }
  1893.  
  1894.                         Close(SomeFile);
  1895.  
  1896.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  1897.  
  1898.                         if(Config -> MiscConfig -> CreateIcons)
  1899.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  1900.                     }
  1901.                 }
  1902.                 else
  1903.                     Error = IoErr();
  1904.  
  1905.                 if(Error)
  1906.                     ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  1907.  
  1908.                 FreeAslRequest(FileRequest);
  1909.             }
  1910.  
  1911.             ReleaseWindows();
  1912.  
  1913.             break;
  1914.  
  1915.             /* Print the screen (pure ASCII). */
  1916.  
  1917.         case MEN_PRINT_SCREEN:
  1918.  
  1919.             BlockWindows();
  1920.  
  1921.             if(RasterEnabled)
  1922.                 PrintSomething(PRINT_SCREEN);
  1923.             else
  1924.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1925.  
  1926.             ReleaseWindows();
  1927.  
  1928.             break;
  1929.  
  1930.             /* Print the clipboard contents. */
  1931.  
  1932.         case MEN_PRINT_CLIP:
  1933.  
  1934.             BlockWindows();
  1935.  
  1936.             PrintSomething(PRINT_CLIP);
  1937.  
  1938.             ReleaseWindows();
  1939.  
  1940.             break;
  1941.  
  1942.             /* Open/close the terminal capture file. */
  1943.  
  1944.         case MEN_CAPTURE_TO_FILE:
  1945.  
  1946.             if(FileCapture)
  1947.                 CloseFileCapture();
  1948.             else
  1949.                 OpenFileCapture();
  1950.  
  1951.             break;
  1952.  
  1953.             /* Start/terminate the printer
  1954.              * capture.
  1955.              */
  1956.  
  1957.         case MEN_CAPTURE_TO_PRINTER:
  1958.  
  1959.             if(PrinterCapture)
  1960.                 ClosePrinterCapture(TRUE);
  1961.             else
  1962.                 OpenPrinterCapture(FALSE);
  1963.  
  1964.             break;
  1965.  
  1966.             /* Iconify the program. */
  1967.  
  1968.         case MEN_ICONIFY:
  1969.  
  1970.             if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  1971.             {
  1972.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  1973.                     break;
  1974.             }
  1975.  
  1976.             DoIconify = TRUE;
  1977.  
  1978.             break;
  1979.  
  1980.             /* Say who we are. */
  1981.  
  1982.         case MEN_ABOUT:
  1983.  
  1984.             BlockWindows();
  1985.  
  1986. #ifdef DATAFEED
  1987.             {
  1988.                 extern BPTR DataFeed;
  1989.  
  1990.                 if(DataFeed)
  1991.                 {
  1992.                     Close(DataFeed);
  1993.  
  1994.                     DataFeed = NULL;
  1995.                 }
  1996.  
  1997.                 if(FileRequest = GetFile(Window,"Select terminal test file","","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
  1998.                 {
  1999.                     if(GetFileSize(DummyBuffer))
  2000.                     {
  2001.                         if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
  2002.                         {
  2003.                             if(Kick30)
  2004.                                 SetVBuf(DataFeed,NULL,2,8192);
  2005.                         }
  2006.                     }
  2007.  
  2008.                     FreeAslRequest(FileRequest);
  2009.                 }
  2010.             }
  2011. #else
  2012.             ShowAbout(FALSE);
  2013. #endif    /* DATAFEED */
  2014.             ReleaseWindows();
  2015.  
  2016.             break;
  2017.  
  2018.             /* Terminate the program. */
  2019.  
  2020.         case MEN_QUIT:
  2021.  
  2022.             if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2023.                 MainTerminated = TRUE;
  2024.             else
  2025.             {
  2026.                 STRPTR    Buffer;
  2027.                 LONG    OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
  2028.  
  2029.                 OldLen = Len;
  2030.  
  2031.                 if(Online)
  2032.                     Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
  2033.  
  2034.                 if(BufferChanged)
  2035.                     Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
  2036.  
  2037.                 if(ConfigChanged)
  2038.                     Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
  2039.  
  2040.                 if(PhonebookChanged)
  2041.                     Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
  2042.  
  2043.                 if(TranslationChanged)
  2044.                     Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
  2045.  
  2046.                 if(MacroChanged)
  2047.                     Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
  2048.  
  2049.                 if(CursorKeysChanged)
  2050.                     Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
  2051.  
  2052.                 if(FastMacrosChanged)
  2053.                     Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
  2054.  
  2055.                 if(HotkeysChanged)
  2056.                     Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
  2057.  
  2058.                 if(SpeechChanged)
  2059.                     Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
  2060.  
  2061.                 if(SoundChanged)
  2062.                     Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
  2063.  
  2064.                 BlockWindows();
  2065.  
  2066.                 OldPtr = ThisProcess -> pr_WindowPtr;
  2067.  
  2068.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  2069.  
  2070.                 if(OldLen != Len)
  2071.                 {
  2072.                     if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
  2073.                     {
  2074.                         SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
  2075.  
  2076.                         if(Online)
  2077.                         {
  2078.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
  2079.  
  2080.                             strcat(Buffer,SharedBuffer);
  2081.                         }
  2082.  
  2083.                         if(BufferChanged)
  2084.                         {
  2085.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
  2086.  
  2087.                             strcat(Buffer,SharedBuffer);
  2088.                         }
  2089.  
  2090.                         if(ConfigChanged)
  2091.                         {
  2092.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
  2093.  
  2094.                             strcat(Buffer,SharedBuffer);
  2095.                         }
  2096.  
  2097.                         if(PhonebookChanged)
  2098.                         {
  2099.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
  2100.  
  2101.                             strcat(Buffer,SharedBuffer);
  2102.                         }
  2103.  
  2104.                         if(TranslationChanged)
  2105.                         {
  2106.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
  2107.  
  2108.                             strcat(Buffer,SharedBuffer);
  2109.                         }
  2110.  
  2111.                         if(MacroChanged)
  2112.                         {
  2113.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
  2114.  
  2115.                             strcat(Buffer,SharedBuffer);
  2116.                         }
  2117.  
  2118.                         if(CursorKeysChanged)
  2119.                         {
  2120.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
  2121.  
  2122.                             strcat(Buffer,SharedBuffer);
  2123.                         }
  2124.  
  2125.                         if(FastMacrosChanged)
  2126.                         {
  2127.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
  2128.  
  2129.                             strcat(Buffer,SharedBuffer);
  2130.                         }
  2131.  
  2132.                         if(HotkeysChanged)
  2133.                         {
  2134.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
  2135.  
  2136.                             strcat(Buffer,SharedBuffer);
  2137.                         }
  2138.  
  2139.                         if(SpeechChanged)
  2140.                         {
  2141.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
  2142.  
  2143.                             strcat(Buffer,SharedBuffer);
  2144.                         }
  2145.  
  2146.                         if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2147.                             MainTerminated = TRUE;
  2148.  
  2149.                         FreeVecPooled(Buffer);
  2150.                     }
  2151.                     else
  2152.                         MainTerminated = TRUE;
  2153.                 }
  2154.                 else
  2155.                     MainTerminated = TRUE;
  2156.  
  2157.                 ThisProcess -> pr_WindowPtr = OldPtr;
  2158.  
  2159.                 ReleaseWindows();
  2160.             }
  2161.  
  2162.             break;
  2163.  
  2164.             /* Feed the contents of the clipboard
  2165.              * into the input stream.
  2166.              */
  2167.  
  2168.         case MEN_PASTE:
  2169.  
  2170.             if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
  2171.             {
  2172.                 ClipInput = TRUE;
  2173.  
  2174.                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2175.                     ClipXerox = TRUE;
  2176.             }
  2177.             else
  2178.                 ClipInput = FALSE;
  2179.  
  2180.             break;
  2181.  
  2182.         case MEN_COPY:
  2183.  
  2184.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2185.                 ClipMarker(TRUE);
  2186.             else
  2187.                 ClipMarker(FALSE);
  2188.  
  2189.             break;
  2190.  
  2191.         case MEN_CLEAR:
  2192.  
  2193.             DropMarker();
  2194.             break;
  2195.  
  2196.             /* Execute an AmigaDOS command. */
  2197.  
  2198.         case MEN_EXECUTE_DOS_COMMAND:
  2199.  
  2200.             BlockWindows();
  2201.  
  2202.                 /* Enter the name of the command. */
  2203.  
  2204.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
  2205.                 SendAmigaDOSCommand(AmigaDOSCommandBuffer);
  2206.  
  2207.             ReleaseWindows();
  2208.  
  2209.             break;
  2210.  
  2211.             /* Execute an ARexx script command. */
  2212.  
  2213.         case MEN_EXECUTE_REXX_COMMAND:
  2214.  
  2215.             BlockWindows();
  2216.  
  2217.                 /* Get the rexx file name/program. */
  2218.  
  2219.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
  2220.                 SendARexxCommand(ARexxCommandBuffer);
  2221.  
  2222.             ReleaseWindows();
  2223.  
  2224.             break;
  2225.  
  2226.             /* Turn recording on/off. */
  2227.  
  2228.         case MEN_RECORD:
  2229.  
  2230.             if(GetItem(MEN_RECORD))
  2231.             {
  2232.                 if(!Recording)
  2233.                 {
  2234.                     if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
  2235.                     {
  2236.                         RememberResetOutput();
  2237.                         RememberResetInput();
  2238.  
  2239.                         RememberOutput = TRUE;
  2240.  
  2241.                         Recording = TRUE;
  2242.                         RecordingLine = FALSE;
  2243.  
  2244.                         OnItem(MEN_RECORD_LINE);
  2245.                     }
  2246.                 }
  2247.             }
  2248.             else
  2249.             {
  2250.                 if(Recording)
  2251.                 {
  2252.                     FinishRecord();
  2253.  
  2254.                     RememberOutput = FALSE;
  2255.                     RememberInput = FALSE;
  2256.  
  2257.                     Recording = FALSE;
  2258.                     RecordingLine = FALSE;
  2259.  
  2260.                     OffItem(MEN_RECORD_LINE);
  2261.                 }
  2262.             }
  2263.  
  2264.             break;
  2265.  
  2266.         case MEN_RECORD_LINE:
  2267.  
  2268.             if(Recording)
  2269.             {
  2270.                 if(GetItem(MEN_RECORD))
  2271.                 {
  2272.                     if(!RecordingLine)
  2273.                     {
  2274.                         RecordingLine = TRUE;
  2275.  
  2276.                         RememberResetInput();
  2277.  
  2278.                         RememberOutput = FALSE;
  2279.                         RememberInput = TRUE;
  2280.                     }
  2281.                 }
  2282.                 else
  2283.                 {
  2284.                     if(RecordingLine)
  2285.                     {
  2286.                         RememberSpill();
  2287.  
  2288.                         RecordingLine = FALSE;
  2289.  
  2290.                         RememberOutput = TRUE;
  2291.                         RememberInput = FALSE;
  2292.                     }
  2293.                 }
  2294.             }
  2295.  
  2296.             break;
  2297.  
  2298.         case MEN_DISABLE_TRAPS:
  2299.  
  2300.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2301.             {
  2302.                 ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2303.  
  2304.                 if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
  2305.                     WatchTraps = TRUE;
  2306.                 else
  2307.                     WatchTraps = FALSE;
  2308.  
  2309.                 ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2310.             }
  2311.  
  2312.             break;
  2313.  
  2314.             /* Edit the trap settings? */
  2315.  
  2316.         case MEN_EDIT_TRAPS:
  2317.  
  2318.             BlockWindows();
  2319.  
  2320.             TrapPanel();
  2321.  
  2322.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2323.             {
  2324.                 if(WatchTraps)
  2325.                     Item -> Flags &= ~CHECKED;
  2326.                 else
  2327.                     Item -> Flags |= CHECKED;
  2328.             }
  2329.  
  2330.             ReleaseWindows();
  2331.  
  2332.             break;
  2333.  
  2334.             /* Set the name we will use to open the
  2335.              * default console output window for
  2336.              * AmigaDOS commands and ARexx scripts.
  2337.              */
  2338.  
  2339.         case MEN_SET_CONSOLE:
  2340.  
  2341.             BlockWindows();
  2342.  
  2343.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  2344.                 SetEnvDOS("TERMWINDOW",WindowName);
  2345.  
  2346.             ReleaseWindows();
  2347.  
  2348.             break;
  2349.  
  2350.             /* Open the phonebook and dial the
  2351.              * list of entries the user will select.
  2352.              */
  2353.  
  2354.         case MEN_PHONEBOOK:
  2355.  
  2356.             BlockWindows();
  2357.  
  2358.             HandleLocalDialList(TRUE);
  2359.  
  2360.             while(PhonePanel())
  2361.             {
  2362.                 if(!DialPanel())
  2363.                 {
  2364.                     Status = OldStatus;
  2365.  
  2366.                     break;
  2367.                 }
  2368.  
  2369.                 Status = OldStatus;
  2370.             }
  2371.  
  2372.             SetRedialMenu();
  2373.  
  2374.             ReleaseWindows();
  2375.  
  2376.             break;
  2377.  
  2378.             /* Redial those dial list entries which
  2379.              * we were unable to connect.
  2380.              */
  2381.  
  2382.         case MEN_REDIAL:
  2383.  
  2384.             BlockWindows();
  2385.  
  2386.             HandleLocalDialList(TRUE);
  2387.  
  2388.             do
  2389.             {
  2390.                 if(!DialPanel())
  2391.                 {
  2392.                     Status = OldStatus;
  2393.  
  2394.                     break;
  2395.                 }
  2396.  
  2397.                 Status = OldStatus;
  2398.             }
  2399.             while(PhonePanel());
  2400.  
  2401.             SetRedialMenu();
  2402.  
  2403.             ReleaseWindows();
  2404.  
  2405.             break;
  2406.  
  2407.             /* Dial a single number. */
  2408.  
  2409.         case MEN_DIAL_NUMBER:
  2410.  
  2411.             BlockWindows();
  2412.  
  2413.             HandleLocalDialList(TRUE);
  2414.  
  2415.             DummyBuffer[0] = 0;
  2416.  
  2417.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DummyBuffer))
  2418.             {
  2419.                 if(DummyBuffer[0])
  2420.                 {
  2421.                     struct List *LocalList;
  2422.  
  2423.                     if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2424.                     {
  2425.                         struct PhoneNode    *DialNode;
  2426.                         LONG             Len = strlen(DummyBuffer);
  2427.  
  2428.                         NewList(LocalList);
  2429.  
  2430.                         if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
  2431.                         {
  2432.                             DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
  2433.  
  2434.                             strcpy(DialNode -> VanillaNode . ln_Name,DummyBuffer);
  2435.  
  2436.                             AddTail(LocalList,&DialNode -> VanillaNode);
  2437.  
  2438.                             FreeDialList(TRUE);
  2439.  
  2440.                             DialList = LocalList;
  2441.  
  2442.                             DialPanel();
  2443.  
  2444.                             Status = OldStatus;
  2445.                         }
  2446.                         else
  2447.                             FreeVecPooled(LocalList);
  2448.                     }
  2449.                 }
  2450.             }
  2451.  
  2452.             SetRedialMenu();
  2453.  
  2454.             ReleaseWindows();
  2455.  
  2456.             break;
  2457.  
  2458.             /* Send a break across the serial line. */
  2459.  
  2460.         case MEN_SEND_BREAK:
  2461.  
  2462.             SendBreak();
  2463.             break;
  2464.  
  2465.             /* Hang up the phone line. */
  2466.  
  2467.         case MEN_HANG_UP:
  2468.  
  2469.             BlockWindows();
  2470.  
  2471.             if(DialMsg)
  2472.             {
  2473.                 DialMsg -> rm_Result1 = RC_WARN;
  2474.                 DialMsg -> rm_Result2 = 0;
  2475.  
  2476.                 ReplyMsg(DialMsg);
  2477.  
  2478.                 DialMsg = NULL;
  2479.             }
  2480.  
  2481.             HangUp();
  2482.  
  2483.                 /* Remember online state. */
  2484.  
  2485.             WasOnline = Online;
  2486.  
  2487.                 /* We are no longer online. */
  2488.  
  2489.             Online = FALSE;
  2490.  
  2491.                 /* Clear the password. */
  2492.  
  2493.             Password[0]        = 0;
  2494.             UserName[0]        = 0;
  2495.  
  2496.             CurrentBBSName[0]    = 0;
  2497.             CurrentBBSComment[0]    = 0;
  2498.             CurrentBBSNumber[0]    = 0;
  2499.  
  2500.                 /* Reset time limit. */
  2501.  
  2502.             LimitCount = -1;
  2503.  
  2504.                 /* Note the  last action. */
  2505.  
  2506.             if(CurrentPay)
  2507.             {
  2508.                     /* Reset the text rendering styles, font, etc. in
  2509.                      * order to keep the following text from getting
  2510.                      * illegible.
  2511.                      */
  2512.  
  2513.                 SoftReset();
  2514.  
  2515.                     /* Display how much we expect
  2516.                      * the user will have to pay for
  2517.                      * this call.
  2518.                      */
  2519.  
  2520.                 ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  2521.  
  2522.                 LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
  2523.  
  2524.                 CurrentPay = 0;
  2525.             }
  2526.             else
  2527.                 LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  2528.  
  2529.             SoundPlay(SOUND_DISCONNECT);
  2530.  
  2531.             ReleaseWindows();
  2532.  
  2533.                 /* Execute logoff macro. */
  2534.  
  2535.             if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
  2536.                 SerialCommand(Config -> CommandConfig -> LogoffMacro);
  2537.  
  2538.                 /* Update the logfile. */
  2539.  
  2540.             StopCall(FALSE);
  2541.  
  2542.                 /* Don't execute the logoff macro twice. */
  2543.  
  2544.             WasOnline = FALSE;
  2545.  
  2546.             ChosenEntry = NULL;
  2547.  
  2548.                 /* Enable the dialing functions. */
  2549.  
  2550.             SetDialMenu(TRUE);
  2551.  
  2552.                 /* Previous configuration available? */
  2553.  
  2554.             if(BackupConfig)
  2555.             {
  2556.                     /* Remember old configuration. */
  2557.  
  2558.                 SaveConfig(Config,PrivateConfig);
  2559.  
  2560.                     /* Copy configuration. */
  2561.  
  2562.                 SaveConfig(BackupConfig,Config);
  2563.  
  2564.                     /* Set up new configuration. */
  2565.  
  2566.                 ConfigSetup();
  2567.  
  2568.                     /* Free old configuration. */
  2569.  
  2570.                 DeleteConfiguration(BackupConfig);
  2571.  
  2572.                 BackupConfig = NULL;
  2573.             }
  2574.  
  2575.             if(Config -> ModemConfig -> RedialAfterHangup)
  2576.             {
  2577.                 if(DialList)
  2578.                 {
  2579.                     if(DialList -> lh_Head -> ln_Succ)
  2580.                         DoDial = DIAL_REDIAL;
  2581.                 }
  2582.             }
  2583.  
  2584.             break;
  2585.  
  2586.             /* Wait a bit... */
  2587.  
  2588.         case MEN_WAIT:
  2589.         {
  2590.             struct Window        *ReqWindow;
  2591.             struct EasyStruct     Easy;
  2592.  
  2593.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2594.             Easy . es_Flags        = NULL;
  2595.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2596.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  2597.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
  2598.  
  2599.             BlockWindows();
  2600.  
  2601.             if(ReqWindow = BuildEasyRequest(Window,&Easy,NULL))
  2602.             {
  2603.                 ULONG    Signals;
  2604.                 BYTE    Done = FALSE;
  2605.  
  2606.                     /* Don't echo serial output. */
  2607.  
  2608.                 Quiet = TRUE;
  2609.  
  2610.                 do
  2611.                 {
  2612.                     SerWrite(" \b",2);
  2613.  
  2614.                     HandleSerial();
  2615.  
  2616.                     StartTime(1,0);
  2617.  
  2618.                     Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
  2619.  
  2620.                     if(Signals & SIG_TIMER)
  2621.                         WaitIO(TimeRequest);
  2622.  
  2623.                     if(Signals & PORTMASK(ReqWindow -> UserPort))
  2624.                     {
  2625.                         if(!SysReqHandler(ReqWindow,NULL,FALSE))
  2626.                         {
  2627.                             Done = TRUE;
  2628.  
  2629.                             if(!CheckIO(TimeRequest))
  2630.                                 AbortIO(TimeRequest);
  2631.  
  2632.                             WaitIO(TimeRequest);
  2633.                         }
  2634.                     }
  2635.                 }
  2636.                 while(!Done);
  2637.  
  2638.                 Quiet = FALSE;
  2639.  
  2640.                 FreeSysRequest(ReqWindow);
  2641.             }
  2642.  
  2643.             ReleaseWindows();
  2644.         }
  2645.  
  2646.         break;
  2647.  
  2648.             /* Flush the serial buffers. */
  2649.  
  2650.         case MEN_FLUSH_BUFFER:
  2651.  
  2652.             ClearSerial();
  2653.  
  2654.             RestartSerial(FALSE);
  2655.  
  2656.             break;
  2657.  
  2658.             /* Release the serial device for other
  2659.              * applications.
  2660.              */
  2661.  
  2662.         case MEN_RELEASE_DEVICE:
  2663.  
  2664.             ReleaseSerial = TRUE;
  2665.             break;
  2666.  
  2667.         case MEN_UPLOAD_ASCII:
  2668.  
  2669.             BlockWindows();
  2670.  
  2671.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary))
  2672.             {
  2673.                 BinaryTransfer = FALSE;
  2674.  
  2675.                 StartXprSend(TRANSFER_ASCII,TRUE);
  2676.  
  2677.                 BinaryTransfer = TRUE;
  2678.             }
  2679.  
  2680.             ResetProtocol();
  2681.  
  2682.             ReleaseWindows();
  2683.  
  2684.             break;
  2685.  
  2686.         case MEN_DOWNLOAD_ASCII:
  2687.  
  2688.             BlockWindows();
  2689.  
  2690.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary))
  2691.             {
  2692.                 BinaryTransfer = FALSE;
  2693.  
  2694.                 StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  2695.  
  2696.                 BinaryTransfer = TRUE;
  2697.             }
  2698.  
  2699.             ResetProtocol();
  2700.  
  2701.             ReleaseWindows();
  2702.  
  2703.             break;
  2704.  
  2705.         case MEN_UPLOAD_TEXT:
  2706.  
  2707.             BlockWindows();
  2708.  
  2709.             if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary))
  2710.             {
  2711.                 BinaryTransfer = FALSE;
  2712.  
  2713.                 StartXprSend(TRANSFER_TEXT,TRUE);
  2714.  
  2715.                 BinaryTransfer = TRUE;
  2716.             }
  2717.  
  2718.             ResetProtocol();
  2719.  
  2720.             ReleaseWindows();
  2721.  
  2722.             break;
  2723.  
  2724.         case MEN_DOWNLOAD_TEXT:
  2725.  
  2726.             BlockWindows();
  2727.  
  2728.             if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary))
  2729.             {
  2730.                 BinaryTransfer = FALSE;
  2731.  
  2732.                 StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  2733.  
  2734.                 BinaryTransfer = TRUE;
  2735.             }
  2736.  
  2737.             ResetProtocol();
  2738.  
  2739.             ReleaseWindows();
  2740.  
  2741.             break;
  2742.  
  2743.             /* Edit and transfer a file. */
  2744.  
  2745.         case MEN_EDIT_AND_UPLOAD_TEXT:
  2746.  
  2747.             BlockWindows();
  2748.  
  2749.             if(!Config -> PathConfig -> Editor[0])
  2750.                 GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
  2751.  
  2752.             if(Config -> PathConfig -> Editor[0])
  2753.             {
  2754.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
  2755.                 {
  2756.                     UBYTE CompoundName[512];
  2757.  
  2758.                     strcpy(CompoundName,Config -> PathConfig -> Editor);
  2759.                     strcat(CompoundName," \"");
  2760.                     strcat(CompoundName,DummyBuffer);
  2761.                     strcat(CompoundName,"\"");
  2762.  
  2763.                     SystemTags(CompoundName,
  2764.                         SYS_UserShell,    TRUE,
  2765.                     TAG_DONE);
  2766.  
  2767.                     BumpWindow(Window);
  2768.  
  2769.                     FreeAslRequest(FileRequest);
  2770.  
  2771.                     if(GetFileSize(DummyBuffer))
  2772.                     {
  2773.                         BinaryTransfer = FALSE;
  2774.  
  2775.                         switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  2776.                         {
  2777.                             case 1:    if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary))
  2778.                                     SendTextFile(TRANSFER_ASCII,DummyBuffer);
  2779.  
  2780.                                 ResetProtocol();
  2781.  
  2782.                                 break;
  2783.  
  2784.                             case 2:    if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary))
  2785.                                     SendTextFile(TRANSFER_TEXT,DummyBuffer);
  2786.  
  2787.                                 ResetProtocol();
  2788.  
  2789.                                 break;
  2790.                         }
  2791.  
  2792.                         BinaryTransfer = TRUE;
  2793.                     }
  2794.                 }
  2795.             }
  2796.  
  2797.             ReleaseWindows();
  2798.             break;
  2799.  
  2800.         case MEN_UPLOAD_BINARY:
  2801.  
  2802.             BlockWindows();
  2803.  
  2804.             if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary))
  2805.             {
  2806.                 BinaryTransfer = TRUE;
  2807.  
  2808.                 StartXprSend(TRANSFER_BINARY,TRUE);
  2809.             }
  2810.  
  2811.             ResetProtocol();
  2812.  
  2813.             ReleaseWindows();
  2814.  
  2815.             break;
  2816.  
  2817.             /* Download some files. */
  2818.  
  2819.         case MEN_DOWNLOAD_BINARY:
  2820.  
  2821.             BlockWindows();
  2822.  
  2823.             if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary))
  2824.             {
  2825.                 BinaryTransfer = TRUE;
  2826.  
  2827.                 StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  2828.             }
  2829.  
  2830.             ResetProtocol();
  2831.  
  2832.             ReleaseWindows();
  2833.  
  2834.             break;
  2835.  
  2836.             /* Clear the contents of the scrollback
  2837.              * buffer.
  2838.              */
  2839.  
  2840.         case MEN_CLEAR_BUFFER:
  2841.  
  2842.             if(Lines)
  2843.             {
  2844.                 BlockWindows();
  2845.  
  2846.                 if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2847.                 {
  2848.                     FreeBuffer();
  2849.  
  2850.                     TerminateBuffer();
  2851.                 }
  2852.                 else
  2853.                 {
  2854.                     if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  2855.                     {
  2856.                         FreeBuffer();
  2857.  
  2858.                         TerminateBuffer();
  2859.                     }
  2860.                 }
  2861.  
  2862.                 ReleaseWindows();
  2863.             }
  2864.  
  2865.             break;
  2866.  
  2867.             /* Display the scrollback buffer.
  2868.              * Notify the scrollback task or
  2869.              * fire it off if approriate.
  2870.              */
  2871.  
  2872.         case MEN_DISPLAY_BUFFER:
  2873.  
  2874.             if(!LaunchBuffer())
  2875.             {
  2876.                 BlockWindows();
  2877.  
  2878.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2879.  
  2880.                 ReleaseWindows();
  2881.             }
  2882.  
  2883.             break;
  2884.  
  2885.             /* Close the buffer display. */
  2886.  
  2887.         case MEN_CLOSE_BUFFER:
  2888.  
  2889.             if(BufferTask)
  2890.             {
  2891.                 Forbid();
  2892.  
  2893.                 Signal(BufferTask,SIG_KILL);
  2894.  
  2895.                 ClrSignal(SIG_HANDSHAKE);
  2896.  
  2897.                 Wait(SIG_HANDSHAKE);
  2898.  
  2899.                 Permit();
  2900.             }
  2901.  
  2902.             break;
  2903.  
  2904.             /* Is the buffer to be frozen? */
  2905.  
  2906.         case MEN_FREEZE_BUFFER:
  2907.  
  2908.             BufferFrozen ^= TRUE;
  2909.  
  2910.             CheckItem(MEN_FREEZE_BUFFER,BufferFrozen);
  2911.  
  2912.             Forbid();
  2913.  
  2914.             ConOutputUpdate();
  2915.  
  2916.             Permit();
  2917.  
  2918.             break;
  2919.  
  2920.             /* Load the buffer contents from a file. */
  2921.  
  2922.         case MEN_OPEN_BUFFER:
  2923.  
  2924.             BlockWindows();
  2925.  
  2926.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  2927.             {
  2928.                 if(GetFileSize(DummyBuffer))
  2929.                 {
  2930.                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  2931.                     {
  2932.                         if(Lines)
  2933.                         {
  2934.                             switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  2935.                             {
  2936.                                 case 1:    FreeBuffer();
  2937.                                     break;
  2938.  
  2939.                                 case 2:    break;
  2940.  
  2941.                                 case 0:    Close(SomeFile);
  2942.                                     SomeFile = NULL;
  2943.                                     break;
  2944.                             }
  2945.                         }
  2946.  
  2947.                         if(SomeFile)
  2948.                         {
  2949.                             LONG Len;
  2950.  
  2951.                             LineRead(NULL,NULL,NULL);
  2952.  
  2953.                             while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
  2954.                                 StoreBuffer(DummyBuffer,Len);
  2955.  
  2956.                             Close(SomeFile);
  2957.  
  2958.                             BufferChanged = TRUE;
  2959.                         }
  2960.                     }
  2961.                     else
  2962.                         ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  2963.                 }
  2964.  
  2965.                 FreeAslRequest(FileRequest);
  2966.             }
  2967.  
  2968.             ReleaseWindows();
  2969.             break;
  2970.  
  2971.             /* Save the contents of the scrollback
  2972.              * buffer to a file (line by line).
  2973.              */
  2974.  
  2975.         case MEN_SAVE_BUFFER_AS:
  2976.  
  2977.             BlockWindows();
  2978.  
  2979.             if(!Lines || !BufferLines)
  2980.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2981.             else
  2982.             {
  2983.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  2984.                 {
  2985.                     LONG Error = 0;
  2986.  
  2987.                     SomeFile = NULL;
  2988.  
  2989.                         /* If the file we are about
  2990.                          * to create already exists,
  2991.                          * ask the user whether we are
  2992.                          * to create, append or skip
  2993.                          * the file.
  2994.                          */
  2995.  
  2996.                     if(GetFileSize(DummyBuffer))
  2997.                     {
  2998.                         switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2999.                         {
  3000.                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3001.                                 break;
  3002.  
  3003.                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  3004.                                 {
  3005.                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  3006.                                     {
  3007.                                         Close(SomeFile);
  3008.  
  3009.                                         SomeFile = NULL;
  3010.                                     }
  3011.                                 }
  3012.  
  3013.                                 break;
  3014.                         }
  3015.                     }
  3016.                     else
  3017.                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3018.  
  3019.                     if(SomeFile)
  3020.                     {
  3021.                         LONG i,Len;
  3022.  
  3023.                             /* Obtain the semaphore required
  3024.                              * to gain access to the line buffer
  3025.                              */
  3026.  
  3027.                         ObtainSemaphore(BufferSemaphore);
  3028.  
  3029.                         for(i = 0 ; i < Lines ; i++)
  3030.                         {
  3031.                             Len = BufferLines[i][-1];
  3032.  
  3033.                             if(Len)
  3034.                             {
  3035.                                 SetIoErr(0);
  3036.  
  3037.                                 if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
  3038.                                 {
  3039.                                     Error = IoErr();
  3040.  
  3041.                                     break;
  3042.                                 }
  3043.                             }
  3044.  
  3045.                             SetIoErr(0);
  3046.  
  3047.                             if(FPrintf(SomeFile,"\n") < 1)
  3048.                             {
  3049.                                 Error = IoErr();
  3050.  
  3051.                                 break;
  3052.                             }
  3053.                         }
  3054.  
  3055.                         ReleaseSemaphore(BufferSemaphore);
  3056.  
  3057.                         Close(SomeFile);
  3058.  
  3059.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  3060.  
  3061.                         if(Config -> MiscConfig -> CreateIcons)
  3062.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  3063.  
  3064.                         BufferChanged = FALSE;
  3065.                     }
  3066.                     else
  3067.                         Error = IoErr();
  3068.  
  3069.                     if(Error)
  3070.                         ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3071.  
  3072.                     FreeAslRequest(FileRequest);
  3073.                 }
  3074.             }
  3075.  
  3076.             ReleaseWindows();
  3077.  
  3078.             break;
  3079.  
  3080.             /* Simply clear the screen and move the
  3081.              * cursor to its home position.
  3082.              */
  3083.  
  3084.         case MEN_CLEAR_SCREEN:
  3085.  
  3086.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3087.                 XEmulatorClearConsole(XEM_IO);
  3088.             else
  3089.             {
  3090.                 DropMarker();
  3091.  
  3092.                 ConBypass("\033[2J\033[H",-1);
  3093.             }
  3094.  
  3095.             break;
  3096.  
  3097.             /* Reset the current text rendering font. */
  3098.  
  3099.         case MEN_RESET_FONT:
  3100.  
  3101.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3102.                 XEmulatorResetCharset(XEM_IO);
  3103.             else
  3104.             {
  3105.                 DropMarker();
  3106.  
  3107.                 CurrentFont = TextFont;
  3108.  
  3109.                 SetFont(RPort,CurrentFont);
  3110.  
  3111.                 ConOutputUpdate();
  3112.             }
  3113.  
  3114.             break;
  3115.  
  3116.             /* Reset the display styles and restore
  3117.              * the colours.
  3118.              */
  3119.  
  3120.         case MEN_RESET_STYLES:
  3121.  
  3122.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3123.                 XEmulatorResetTextStyles(XEM_IO);
  3124.             else
  3125.             {
  3126.                 DropMarker();
  3127.  
  3128.                 ConBypass("\033[0m",-1);
  3129.  
  3130.                 ObtainTerminal();
  3131.  
  3132.                 ClearCursor();
  3133.  
  3134.                 Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  3135.  
  3136.                 FgPen = GetPenIndex(SafeTextPen);
  3137.                 BgPen = 0;
  3138.  
  3139.                 if(ReadAPen(RPort) != MappedPens[0][FgPen])
  3140.                     SetAPen(RPort,MappedPens[0][FgPen]);
  3141.  
  3142.                 if(ReadBPen(RPort) != MappedPens[0][BgPen])
  3143.                     SetBPen(RPort,MappedPens[0][BgPen]);
  3144.  
  3145.                 SetWrMsk(RPort,DepthMask);
  3146.  
  3147.                 ConFontScaleUpdate();
  3148.  
  3149.                 DrawCursor();
  3150.  
  3151.                 ReleaseTerminal();
  3152.             }
  3153.  
  3154.             break;
  3155.  
  3156.             /* Reset the whole terminal. */
  3157.  
  3158.         case MEN_RESET_TERMINAL:
  3159.  
  3160.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3161.                 XEmulatorResetConsole(XEM_IO);
  3162.             else
  3163.             {
  3164.                 FreeMarker();
  3165.  
  3166.                 ConBypass("\033c",-1);
  3167.             }
  3168.  
  3169.             break;
  3170.  
  3171.         case MEN_SET_EMULATION:
  3172.  
  3173.             BlockWindows();
  3174.  
  3175.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3176.             {
  3177.                 OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  3178.  
  3179.                 XEmulatorOptions(XEM_IO);
  3180.  
  3181.                 if(NewOptions)
  3182.                 {
  3183.                     SetEmulatorOptions(XEM_PREFS_SAVE);
  3184.  
  3185.                     NewOptions = FALSE;
  3186.                 }
  3187.  
  3188.                 OptionTitle = NULL;
  3189.             }
  3190.             else
  3191.                 EmulationPanel(Config,NULL);
  3192.  
  3193.             ReleaseWindows();
  3194.  
  3195.             break;
  3196.  
  3197.             /* Set the serial preferences. */
  3198.  
  3199.         case MEN_SERIAL:
  3200.  
  3201.             BlockWindows();
  3202.  
  3203.             if(SerialPanel(Config,NULL))
  3204.             {
  3205.                 ConfigSetup();
  3206.  
  3207.                 ConfigChanged = TRUE;
  3208.             }
  3209.  
  3210.             ReleaseWindows();
  3211.  
  3212.             break;
  3213.  
  3214.             /* Set the modem preferences. */
  3215.  
  3216.         case MEN_MODEM:
  3217.  
  3218.             BlockWindows();
  3219.  
  3220.             if(ModemPanel(Config,NULL))
  3221.             {
  3222.                 FlowInit(TRUE);
  3223.  
  3224.                 ConfigChanged = TRUE;
  3225.             }
  3226.  
  3227.             ReleaseWindows();
  3228.  
  3229.             break;
  3230.  
  3231.             /* Set the screen preferences. */
  3232.  
  3233.         case MEN_SCREEN:
  3234.  
  3235.             BlockWindows();
  3236.  
  3237.             if(ScreenPanel(Config,NULL))
  3238.             {
  3239.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3240.                 {
  3241.                     switch(Config -> ScreenConfig -> ColourMode)
  3242.                     {
  3243.                         case COLOUR_EIGHT:
  3244.  
  3245.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3246.                             break;
  3247.  
  3248.                         case COLOUR_SIXTEEN:
  3249.  
  3250.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3251.                             break;
  3252.  
  3253.                         case COLOUR_AMIGA:
  3254.  
  3255.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3256.                             break;
  3257.  
  3258.                         case COLOUR_MONO:
  3259.  
  3260.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3261.                             break;
  3262.                     }
  3263.                 }
  3264.  
  3265.                 ConfigSetup();
  3266.  
  3267.                 ConfigChanged = TRUE;
  3268.             }
  3269.             else
  3270.             {
  3271.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3272.                 {
  3273.                     switch(Config -> ScreenConfig -> ColourMode)
  3274.                     {
  3275.                         case COLOUR_EIGHT:
  3276.  
  3277.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3278.                             break;
  3279.  
  3280.                         case COLOUR_SIXTEEN:
  3281.  
  3282.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3283.                             break;
  3284.  
  3285.                         case COLOUR_AMIGA:
  3286.  
  3287.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3288.                             break;
  3289.  
  3290.                         case COLOUR_MONO:
  3291.  
  3292.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3293.                             break;
  3294.                     }
  3295.  
  3296.                     ConfigChanged = TRUE;
  3297.                 }
  3298.             }
  3299.  
  3300.             ReleaseWindows();
  3301.  
  3302.             break;
  3303.  
  3304.             /* Set the terminal preferences. */
  3305.  
  3306.         case MEN_TERMINAL:
  3307.  
  3308.             BlockWindows();
  3309.  
  3310.             if(TerminalPanel(Config,NULL))
  3311.             {
  3312.                 ConfigSetup();
  3313.  
  3314.                 ConfigChanged = TRUE;
  3315.             }
  3316.  
  3317.             ReleaseWindows();
  3318.  
  3319.             break;
  3320.  
  3321.             /* Set the clipboard preferences. */
  3322.  
  3323.         case MEN_CLIPBOARD:
  3324.  
  3325.             BlockWindows();
  3326.  
  3327.             if(ClipPanel(Config,NULL))
  3328.             {
  3329.                 ConfigSetup();
  3330.  
  3331.                 ConfigChanged = TRUE;
  3332.             }
  3333.  
  3334.             ReleaseWindows();
  3335.  
  3336.             break;
  3337.  
  3338.             /* Set the capture preferences. */
  3339.  
  3340.         case MEN_CAPTURE:
  3341.  
  3342.             BlockWindows();
  3343.  
  3344.             if(CapturePanel(Config,NULL))
  3345.             {
  3346.                 ConfigSetup();
  3347.  
  3348.                 ConfigChanged = TRUE;
  3349.             }
  3350.  
  3351.             ReleaseWindows();
  3352.  
  3353.             break;
  3354.  
  3355.             /* Set the command preferences. */
  3356.  
  3357.         case MEN_COMMANDS:
  3358.  
  3359.             BlockWindows();
  3360.  
  3361.             if(CommandPanel(Config,NULL))
  3362.                 ConfigChanged = TRUE;
  3363.  
  3364.             ReleaseWindows();
  3365.  
  3366.             break;
  3367.  
  3368.             /* Set the miscellaneous preferences. */
  3369.  
  3370.         case MEN_MISC:
  3371.  
  3372.             BlockWindows();
  3373.  
  3374.             if(MiscPanel(Config,NULL))
  3375.             {
  3376.                 ConfigSetup();
  3377.  
  3378.                 ConfigChanged = TRUE;
  3379.             }
  3380.  
  3381.             ReleaseWindows();
  3382.  
  3383.             break;
  3384.  
  3385.             /* Set the path settings. */
  3386.  
  3387.         case MEN_PATH:
  3388.  
  3389.             BlockWindows();
  3390.  
  3391.             if(PathPanel(Config,NULL))
  3392.                 ConfigChanged = TRUE;
  3393.  
  3394.             ReleaseWindows();
  3395.  
  3396.             break;
  3397.  
  3398.             /* Set the file transfer options. */
  3399.  
  3400.         case MEN_TRANSFER:
  3401.  
  3402.             BlockWindows();
  3403.  
  3404.             XprIO -> xpr_filename = NULL;
  3405.  
  3406.                 /* Set up the library options. */
  3407.  
  3408.             if(XProtocolBase)
  3409.             {
  3410.                 XPRCommandSelected = FALSE;
  3411.  
  3412.                 ClearSerial();
  3413.  
  3414.                 NewOptions = FALSE;
  3415.  
  3416.                 TransferBits = XProtocolSetup(XprIO);
  3417.  
  3418.                 RestartSerial(FALSE);
  3419.  
  3420.                 DeleteTransferPanel(TRUE);
  3421.  
  3422.                     /* Successful? */
  3423.  
  3424.                 if(!XPRCommandSelected)
  3425.                 {
  3426.                     if(!(TransferBits & XPRS_SUCCESS))
  3427.                     {
  3428.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  3429.  
  3430.                         CloseLibrary(XProtocolBase);
  3431.  
  3432.                         XProtocolBase = NULL;
  3433.  
  3434.                         LastXprLibrary[0] = 0;
  3435.  
  3436.                         TransferBits = 0;
  3437.  
  3438.                         SetTransferMenu(FALSE);
  3439.                     }
  3440.                     else
  3441.                         SaveProtocolOpts();
  3442.                 }
  3443.             }
  3444.  
  3445.             ReleaseWindows();
  3446.  
  3447.             break;
  3448.  
  3449.             /* Set the file transfer procol settings. */
  3450.  
  3451.         case MEN_TRANSFER_PROTOCOL:
  3452.  
  3453.             BlockWindows();
  3454.  
  3455.             if(LibPanel(Config,NULL))
  3456.             {
  3457.                 ConfigSetup();
  3458.  
  3459.                 ConfigChanged = TRUE;
  3460.             }
  3461.  
  3462.             ReleaseWindows();
  3463.  
  3464.             break;
  3465.  
  3466.             /* Set the translation tables. */
  3467.  
  3468.         case MEN_TRANSLATION:
  3469.  
  3470.             BlockWindows();
  3471.  
  3472.             TranslationChanged |= TranslationPanel();
  3473.  
  3474.                 /* Choose the right console write routine. */
  3475.  
  3476.             ConOutputUpdate();
  3477.  
  3478.             ReleaseWindows();
  3479.  
  3480.             break;
  3481.  
  3482.             /* Set the keyboard macros. */
  3483.  
  3484.         case MEN_MACROS:
  3485.  
  3486.             BlockWindows();
  3487.  
  3488.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3489.             {
  3490.                 XEmulatorMacroKeyFilter(XEM_IO,NULL);
  3491.  
  3492.                 MacroPanel(MacroKeys);
  3493.  
  3494.                 SetupXEM_MacroKeys(MacroKeys);
  3495.             }
  3496.             else
  3497.                 MacroPanel(MacroKeys);
  3498.  
  3499.             ReleaseWindows();
  3500.  
  3501.             break;
  3502.  
  3503.             /* Set the cursor keys. */
  3504.  
  3505.         case MEN_CURSORKEYS:
  3506.  
  3507.             BlockWindows();
  3508.  
  3509.             CursorPanel(CursorKeys);
  3510.  
  3511.             ReleaseWindows();
  3512.  
  3513.             break;
  3514.  
  3515.             /* Set the fast macros. */
  3516.  
  3517.         case MEN_FAST_MACROS:
  3518.  
  3519.             BlockWindows();
  3520.  
  3521.             FastMacroPanel();
  3522.  
  3523.             ReleaseWindows();
  3524.  
  3525.             break;
  3526.  
  3527.             /* Set the hotkey preferences. */
  3528.  
  3529.         case MEN_HOTKEYS:
  3530.  
  3531.             BlockWindows();
  3532.  
  3533.             if(HotkeyPanel(&Hotkeys))
  3534.             {
  3535.                 if(!SetupCx())
  3536.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3537.             }
  3538.  
  3539.             ReleaseWindows();
  3540.  
  3541.             break;
  3542.  
  3543.             /* Set the speech preferences. */
  3544.  
  3545.         case MEN_SPEECH:
  3546.  
  3547.             BlockWindows();
  3548.  
  3549.             SpeechPanel();
  3550.  
  3551.             ReleaseWindows();
  3552.  
  3553.             break;
  3554.  
  3555.             /* Set the sound preferences. */
  3556.  
  3557.         case MEN_SOUND:
  3558.  
  3559.             BlockWindows();
  3560.  
  3561.             if(SoundPanel(&SoundConfig))
  3562.                 SoundInit();
  3563.  
  3564.             ReleaseWindows();
  3565.  
  3566.             break;
  3567.  
  3568.             /* Open the preferences settings. */
  3569.  
  3570.         case MEN_OPEN_SETTINGS:
  3571.  
  3572.             BlockWindows();
  3573.  
  3574.             strcpy(DummyBuffer,LastConfig);
  3575.  
  3576.             DummyChar = PathPart(DummyBuffer);
  3577.  
  3578.             *DummyChar = 0;
  3579.  
  3580.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
  3581.             {
  3582.                 if(ReadConfig(DummyBuffer,PrivateConfig))
  3583.                 {
  3584.                     SwapConfig(PrivateConfig,Config);
  3585.  
  3586.                     strcpy(DummyBuffer,LastConfig);
  3587.  
  3588.                     ConfigSetup();
  3589.  
  3590.                     ConfigChanged = FALSE;
  3591.                 }
  3592.                 else
  3593.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3594.  
  3595.                 FreeAslRequest(FileRequest);
  3596.             }
  3597.  
  3598.             ReleaseWindows();
  3599.  
  3600.             break;
  3601.  
  3602.             /* Save the terminal preferences. */
  3603.  
  3604.         case MEN_SAVE_SETTINGS:
  3605.  
  3606.             if(LastConfig[0])
  3607.             {
  3608.                 BlockWindows();
  3609.  
  3610.                 if(!WriteConfig(LastConfig,Config))
  3611.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
  3612.                 else
  3613.                     ConfigChanged = FALSE;
  3614.  
  3615.                 ReleaseWindows();
  3616.  
  3617.                 break;
  3618.             }
  3619.  
  3620.             /* Save the terminal preferences to a
  3621.              * given file name.
  3622.              */
  3623.  
  3624.         case MEN_SAVE_SETTINGS_AS:
  3625.  
  3626.             BlockWindows();
  3627.  
  3628.             strcpy(DummyBuffer,LastConfig);
  3629.  
  3630.             DummyChar = PathPart(DummyBuffer);
  3631.  
  3632.             *DummyChar = 0;
  3633.  
  3634.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
  3635.             {
  3636.                 if(WriteConfig(DummyBuffer,Config))
  3637.                 {
  3638.                     strcpy(LastConfig,DummyBuffer);
  3639.  
  3640.                     ConfigChanged = FALSE;
  3641.                 }
  3642.                 else
  3643.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3644.  
  3645.                 FreeAslRequest(FileRequest);
  3646.             }
  3647.  
  3648.             ReleaseWindows();
  3649.  
  3650.             break;
  3651.  
  3652.             /* Show terminal information window. */
  3653.  
  3654.         case MEN_STATUS_WINDOW:
  3655.  
  3656.             if(InfoWindow)
  3657.                 CloseInfoWindow();
  3658.             else
  3659.                 OpenInfoWindow();
  3660.  
  3661.             break;
  3662.  
  3663.         case MEN_REVIEW_WINDOW:
  3664.  
  3665.             if(ReviewWindow)
  3666.                 DeleteReview();
  3667.             else
  3668.                 CreateReview();
  3669.  
  3670.             break;
  3671.  
  3672.             /* Open the packet window if necessary, else
  3673.              * just activate it.
  3674.              */
  3675.  
  3676.         case MEN_PACKET_WINDOW:
  3677.  
  3678.             CreatePacketWindow();
  3679.             break;
  3680.  
  3681.             /* Toggle the presence of the fast! macro panel. */
  3682.  
  3683.         case MEN_FAST_MACROS_WINDOW:
  3684.  
  3685.             if(FastWindow)
  3686.                 CloseFastWindow();
  3687.             else
  3688.                 OpenFastWindow();
  3689.  
  3690.             break;
  3691.  
  3692.             /* Open the upload queue window. */
  3693.  
  3694.         case MEN_UPLOAD_QUEUE_WINDOW:
  3695.  
  3696.             CreateQueueProcess();
  3697.             break;
  3698.  
  3699.         default:if(Code >= DIAL_MENU_LIMIT)
  3700.             {
  3701.                 LONG Index = Code - DIAL_MENU_LIMIT;
  3702.  
  3703.                 if(!LocalDialList && !Online)
  3704.                 {
  3705.                     if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
  3706.                     {
  3707.                         LONG i;
  3708.  
  3709.                             /* Clear previous list contents, we
  3710.                              * don't want to redial yet.
  3711.                              */
  3712.  
  3713.                         for(i = 0 ; i < NumPhoneEntries ; i++)
  3714.                             Phonebook[i] -> Count = -1;
  3715.  
  3716.                         NewList(LocalDialList);
  3717.                     }
  3718.                 }
  3719.  
  3720.                 if(Phonebook[Index] -> Count == -1)
  3721.                 {
  3722.                     if(LocalDialList)
  3723.                     {
  3724.                         struct PhoneNode *NewNode;
  3725.  
  3726.                             /* Create a new node to be added to the dial list. */
  3727.  
  3728.                         if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  3729.                         {
  3730.                                 /* Take care of the name and the corresponding phone book entry. */
  3731.  
  3732.                             NewNode -> VanillaNode . ln_Name    = NewNode -> LocalName;
  3733.                             NewNode -> Entry            = Phonebook[Index];
  3734.  
  3735.                             Phonebook[Index] -> Count = ++LocalCount;
  3736.  
  3737.                             SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
  3738.  
  3739.                                 /* Install back-link. */
  3740.  
  3741.                             NewNode -> Entry -> Node = NewNode;
  3742.  
  3743.                             AddTail(LocalDialList,&NewNode -> VanillaNode);
  3744.                         }
  3745.                     }
  3746.                 }
  3747.             }
  3748.  
  3749.             break;
  3750.     }
  3751. }
  3752.  
  3753.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  3754.      *
  3755.      *    Skip along the number of selected menu items and
  3756.      *    handle the associated functions.
  3757.      */
  3758.  
  3759. VOID __regargs
  3760. HandleMenu(ULONG Code,ULONG Qualifier)
  3761. {
  3762.     struct MenuItem *MenuItem;
  3763.  
  3764.     DisplayReopened = FALSE;
  3765.  
  3766.         /* Check until the last menuitem has been
  3767.          * processed.
  3768.          */
  3769.  
  3770.     while(Code != MENUNULL)
  3771.     {
  3772.             /* Pick up the associated menu item. */
  3773.  
  3774.         if(MenuItem = ItemAddress(Menu,Code))
  3775.         {
  3776.             HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
  3777.  
  3778.             if(Apocalypse)
  3779.                 return;
  3780.  
  3781.             if(DisplayReopened)
  3782.             {
  3783.                 DisplayReopened = FALSE;
  3784.  
  3785.                 return;
  3786.             }
  3787.  
  3788.             Code = MenuItem -> NextSelect;
  3789.         }
  3790.         else
  3791.             break;
  3792.     }
  3793.  
  3794.     HandleLocalDialList(FALSE);
  3795. }
  3796.  
  3797.     /* HandleWorkbenchWindow():
  3798.      *
  3799.      *    Handle input coming from the Workbench window.
  3800.      */
  3801.  
  3802. BYTE
  3803. HandleWorkbenchWindow()
  3804. {
  3805.     struct FileInfoBlock    *FileInfo;
  3806.     struct AppMessage    *AppMessage;
  3807.  
  3808.     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  3809.     {
  3810.         struct FileTransferInfo *Info;
  3811.  
  3812.         if(Info = AllocFileTransferInfo())
  3813.         {
  3814.             LONG FilesFound = 0,i;
  3815.             BYTE Success = TRUE;
  3816.  
  3817.             while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  3818.             {
  3819.                 if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
  3820.                 {
  3821.                     for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
  3822.                     {
  3823.                         if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
  3824.                         {
  3825.                             BPTR OldLock;
  3826.  
  3827.                             if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
  3828.                             {
  3829.                                 BPTR FileLock;
  3830.  
  3831.                                 if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
  3832.                                 {
  3833.                                     if(Examine(FileLock,FileInfo))
  3834.                                     {
  3835.                                         if(FileInfo -> fib_DirEntryType < 0)
  3836.                                         {
  3837.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  3838.                                             {
  3839.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  3840.                                                     Success = FALSE;
  3841.                                                 else
  3842.                                                 {
  3843.                                                     FilesFound++;
  3844.  
  3845.                                                     if(Config -> MiscConfig -> TransferIcons)
  3846.                                                     {
  3847.                                                         BPTR InfoLock;
  3848.  
  3849.                                                         strcat(SharedBuffer,".info");
  3850.  
  3851.                                                         if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  3852.                                                         {
  3853.                                                             if(Examine(InfoLock,FileInfo))
  3854.                                                             {
  3855.                                                                 if(FileInfo -> fib_DirEntryType < 0)
  3856.                                                                 {
  3857.                                                                     if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  3858.                                                                         Success = FALSE;
  3859.                                                                     else
  3860.                                                                         FilesFound++;
  3861.                                                                 }
  3862.                                                             }
  3863.  
  3864.                                                             UnLock(InfoLock);
  3865.                                                         }
  3866.                                                     }
  3867.                                                 }
  3868.                                             }
  3869.                                         }
  3870.                                     }
  3871.  
  3872.                                     UnLock(FileLock);
  3873.                                 }
  3874.  
  3875.                                 CurrentDir(OldLock);
  3876.                             }
  3877.                         }
  3878.                     }
  3879.                 }
  3880.  
  3881.                 ReplyMsg((struct Message *)AppMessage);
  3882.             }
  3883.  
  3884.             if(FilesFound)
  3885.             {
  3886.                 SortFileTransferInfo(Info);
  3887.  
  3888.                 BlockWindows();
  3889.  
  3890.                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
  3891.                 {
  3892.                     case 1:    BinaryTransfer        = TRUE;
  3893.                         FileTransferInfo    = Info;
  3894.  
  3895.                         StartXprSendFromList(TRANSFER_BINARY,TRUE);
  3896.  
  3897.                         break;
  3898.  
  3899.                     case 2:    BinaryTransfer        = FALSE;
  3900.                         FileTransferInfo    = Info;
  3901.  
  3902.                         StartXprSendFromList(TRANSFER_TEXT,TRUE);
  3903.  
  3904.                         break;
  3905.  
  3906.                     case 0:    FreeFileTransferInfo(Info);
  3907.                         break;
  3908.                 }
  3909.  
  3910.                 ReleaseWindows();
  3911.             }
  3912.         }
  3913.  
  3914.         FreeDosObject(DOS_FIB,FileInfo);
  3915.     }
  3916.  
  3917.     while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  3918.         ReplyMsg((struct Message *)AppMessage);
  3919.  
  3920.     return(FALSE);
  3921. }
  3922.  
  3923.     /* HandleIconify():
  3924.      *
  3925.      *    Handle program iconification.
  3926.      */
  3927.  
  3928. VOID
  3929. HandleIconify()
  3930. {
  3931.     BYTE Released = FALSE;
  3932.  
  3933.         /* Set the wait mouse pointer... */
  3934.  
  3935.     BlockWindows();
  3936.  
  3937.         /* Open workbench.library. */
  3938.  
  3939.     if(WorkbenchBase)
  3940.     {
  3941.             /* Open icon.library. */
  3942.  
  3943.         if(IconBase)
  3944.         {
  3945.             struct DiskObject *Icon;
  3946.  
  3947.             if(!(Icon = GetProgramIcon()))
  3948.                 Icon = GetDefDiskObject(WBTOOL);
  3949.  
  3950.                 /* Did we get an icon? */
  3951.  
  3952.             if(Icon)
  3953.             {
  3954.                 struct MsgPort *IconPort;
  3955.  
  3956.                     /* Reset the icon type. */
  3957.  
  3958.                 Icon -> do_Type        = NULL;
  3959.  
  3960.                     /* Default icon position. */
  3961.  
  3962.                 Icon -> do_CurrentX    = NO_ICON_POSITION;
  3963.                 Icon -> do_CurrentY    = NO_ICON_POSITION;
  3964.  
  3965.                     /* Create the Workbench reply port. */
  3966.  
  3967.                 if(IconPort = CreateMsgPort())
  3968.                 {
  3969.                     struct AppIcon *AppIcon;
  3970.  
  3971.                         /* Add the application icon. */
  3972.  
  3973.                     if(AppIcon = AddAppIcon(0,0,TermIDString,IconPort,NULL,Icon,TAG_DONE))
  3974.                     {
  3975.                         struct AppMessage    *AppMessage;
  3976.                         UBYTE            *String,*Error;
  3977.                         ULONG             SignalSet;
  3978.  
  3979.                             /* Reset the guardian. */
  3980.  
  3981.                         IconTerminated = FALSE;
  3982.  
  3983.                             /* Release the window. */
  3984.  
  3985.                         Released = TRUE;
  3986.  
  3987.                         ReleaseWindows();
  3988.  
  3989.                         WindowBox . Left    = Window -> LeftEdge;
  3990.                         WindowBox . Top        = Window -> TopEdge;
  3991.                         WindowBox . Width    = Window -> Width;
  3992.                         WindowBox . Height    = Window -> Height;
  3993.  
  3994.                             /* Close the display. full stop. */
  3995.  
  3996.                         if(DeleteDisplay())
  3997.                         {
  3998.                                 /* Reset and release the serial driver. */
  3999.  
  4000.                             if(Config -> MiscConfig -> ReleaseDevice)
  4001.                             {
  4002.                                 ClearSerial();
  4003.  
  4004.                                 DeleteSerial();
  4005.                             }
  4006.  
  4007.                                 /* Wait for double-click. */
  4008.  
  4009. IconLoop:                        while(!IconTerminated)
  4010.                             {
  4011.                                 SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
  4012.  
  4013.                                 if(SignalSet & PORTMASK(IconPort))
  4014.                                 {
  4015.                                         /* Pick up application messages. */
  4016.  
  4017.                                     while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4018.                                     {
  4019.                                             /* Received a double-click? */
  4020.  
  4021.                                         IconTerminated = TRUE;
  4022.  
  4023.                                         ReplyMsg(AppMessage);
  4024.                                     }
  4025.                                 }
  4026.  
  4027.                                     /* Wake up if ARexx command received. */
  4028.  
  4029.                                 if(SignalSet & SIG_REXX)
  4030.                                     while(HandleRexx());
  4031.  
  4032.                                 if(SignalSet & SIGBREAKF_CTRL_F)
  4033.                                     IconTerminated = TRUE;
  4034.                             }
  4035.  
  4036.                                 /* Open the serial driver. */
  4037.  
  4038.                             if(Config -> MiscConfig -> ReleaseDevice)
  4039.                             {
  4040.                                 if(Error = CreateSerial())
  4041.                                 {
  4042.                                     DeleteSerial();
  4043.  
  4044.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  4045.                                     {
  4046.                                         case 1:    IconTerminated = FALSE;
  4047.                                             goto IconLoop;
  4048.  
  4049.                                         case 0:    MainTerminated = TRUE;
  4050.                                     }
  4051.                                 }
  4052.                                 else
  4053.                                 {
  4054.                                     if(SerialMessage)
  4055.                                     {
  4056.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  4057.  
  4058.                                         SerialMessage = NULL;
  4059.                                     }
  4060.                                 }
  4061.                             }
  4062.  
  4063.                             if(CantQuit && MainTerminated)
  4064.                                 MainTerminated = FALSE;
  4065.  
  4066.                                 /* Create the display. */
  4067.  
  4068.                             if(!MainTerminated)
  4069.                             {
  4070.                                 if(String = CreateDisplay(FALSE))
  4071.                                 {
  4072.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  4073.                                     {
  4074.                                         ClearSerial();
  4075.  
  4076.                                         DeleteSerial();
  4077.  
  4078.                                         IconTerminated = FALSE;
  4079.  
  4080.                                         goto IconLoop;
  4081.                                     }
  4082.                                     else
  4083.                                         MainTerminated = FALSE;
  4084.                                 }
  4085.                                 else
  4086.                                 {
  4087.                                     BumpWindow(Window);
  4088.  
  4089.                                     PubScreenStuff();
  4090.                                 }
  4091.                             }
  4092.                         }
  4093.                         else
  4094.                         {
  4095.                             BlockWindows();
  4096.  
  4097.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  4098.  
  4099.                             ReleaseWindows();
  4100.                         }
  4101.  
  4102.                             /* Remove the application icon. */
  4103.  
  4104.                         RemoveAppIcon(AppIcon);
  4105.  
  4106.                             /* Reply pending messages. */
  4107.  
  4108.                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4109.                             ReplyMsg(AppMessage);
  4110.                     }
  4111.                     else
  4112.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4113.  
  4114.                     DeleteMsgPort(IconPort);
  4115.                 }
  4116.                 else
  4117.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4118.  
  4119.                 FreeDiskObject(Icon);
  4120.             }
  4121.             else
  4122.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4123.         }
  4124.         else
  4125.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4126.     }
  4127.     else
  4128.         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4129.  
  4130.     if(!Released)
  4131.         ReleaseWindows();
  4132.  
  4133.         /* Finished! */
  4134.  
  4135.     DoIconify = FALSE;
  4136. }
  4137.  
  4138.     /* HandleOnlineCleanup():
  4139.      *
  4140.      *    Perform offline cleanup tasks.
  4141.      */
  4142.  
  4143. VOID
  4144. HandleOnlineCleanup()
  4145. {
  4146.     SoundPlay(SOUND_DISCONNECT);
  4147.  
  4148.     StopCall(FALSE);
  4149.  
  4150.     if(CurrentPay)
  4151.     {
  4152.             /* Reset the text rendering styles, font, etc. in
  4153.              * order to keep the following text from getting
  4154.              * illegible.
  4155.              */
  4156.  
  4157.         SoftReset();
  4158.  
  4159.             /* Display how much we expect
  4160.              * the user will have to pay for
  4161.              * this call.
  4162.              */
  4163.  
  4164.         ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  4165.  
  4166.         LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
  4167.  
  4168.         CurrentPay = 0;
  4169.     }
  4170.     else
  4171.         LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4172.  
  4173.     SetDialMenu(TRUE);
  4174.  
  4175.         /* Execute logoff macro. */
  4176.  
  4177.     if(Config -> CommandConfig -> LogoffMacro[0])
  4178.         SerialCommand(Config -> CommandConfig -> LogoffMacro);
  4179.  
  4180.         /* Clear the password. */
  4181.  
  4182.     Password[0]        = 0;
  4183.     UserName[0]        = 0;
  4184.  
  4185.     CurrentBBSName[0]    = 0;
  4186.     CurrentBBSComment[0]    = 0;
  4187.     CurrentBBSNumber[0]    = 0;
  4188.  
  4189.     WasOnline = FALSE;
  4190.  
  4191.     ChosenEntry = NULL;
  4192.  
  4193.     LimitCount = -1;
  4194.  
  4195.         /* Previous configuration available? */
  4196.  
  4197.     if(BackupConfig)
  4198.     {
  4199.             /* Remember old configuration. */
  4200.  
  4201.         SaveConfig(Config,PrivateConfig);
  4202.  
  4203.             /* Copy configuration. */
  4204.  
  4205.         SaveConfig(BackupConfig,Config);
  4206.  
  4207.             /* Set up new configuration. */
  4208.  
  4209.         ConfigSetup();
  4210.  
  4211.             /* Free old configuration. */
  4212.  
  4213.         DeleteConfiguration(BackupConfig);
  4214.  
  4215.         BackupConfig = NULL;
  4216.     }
  4217.  
  4218.     if(Config -> ModemConfig -> RedialAfterHangup)
  4219.     {
  4220.         if(DialList)
  4221.         {
  4222.             if(DialList -> lh_Head -> ln_Succ)
  4223.                 DoDial = DIAL_REDIAL;
  4224.         }
  4225.     }
  4226. }
  4227.  
  4228.     /* HandleFlowChange():
  4229.      *
  4230.      *    Handle data flow scanner information.
  4231.      */
  4232.  
  4233. VOID
  4234. HandleFlowChange()
  4235. {
  4236.     if(!Online && (FlowInfo . Voice || FlowInfo . Ring || FlowInfo . Connect))
  4237.     {
  4238.         if(FlowInfo . Voice)
  4239.         {
  4240.             UBYTE DateTimeBuffer[256];
  4241.  
  4242.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4243.  
  4244.             WakeUp(Window,SOUND_VOICE);
  4245.  
  4246.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
  4247.  
  4248.             Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  4249.         }
  4250.  
  4251.         if(FlowInfo . Ring)
  4252.         {
  4253.             UBYTE DateTimeBuffer[256];
  4254.  
  4255.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4256.  
  4257.             WakeUp(Window,SOUND_RING);
  4258.  
  4259.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
  4260.  
  4261.             Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  4262.         }
  4263.  
  4264.         if(FlowInfo . Connect)
  4265.         {
  4266.             WakeUp(Window,SOUND_CONNECT);
  4267.  
  4268.             Online        = TRUE;
  4269.             BaudPending    = FALSE;
  4270.  
  4271.             SetDialMenu(FALSE);
  4272.         }
  4273.     }
  4274.  
  4275.         /* Check if we are to prompt the user for
  4276.          * ZModem upload type.
  4277.          */
  4278.  
  4279.     if(UsesZModem && FlowInfo . ZModemUpload && XProtocolBase)
  4280.     {
  4281.         if(Config -> MiscConfig -> AutoUpload)
  4282.         {
  4283.             BlockWindows();
  4284.  
  4285.             switch(UploadPanel())
  4286.             {
  4287.                 case UPLOAD_TEXT:
  4288.  
  4289.                     BinaryTransfer = FALSE;
  4290.  
  4291.                     if(!StartXprSend(TRANSFER_TEXT,TRUE))
  4292.                         SerWrite(ZModemCancel,20);
  4293.  
  4294.                     break;
  4295.  
  4296.                 case UPLOAD_BINARY:
  4297.  
  4298.                     BinaryTransfer = TRUE;
  4299.  
  4300.                     if(!StartXprSend(TRANSFER_BINARY,TRUE))
  4301.                         SerWrite(ZModemCancel,20);
  4302.  
  4303.                     break;
  4304.  
  4305.                 case UPLOAD_ABORT:
  4306.  
  4307.                     SerWrite(ZModemCancel,20);
  4308.                     break;
  4309.  
  4310.                 case UPLOAD_BINARY_FROM_LIST:
  4311.  
  4312.                     StartUpload(UPLOAD_BINARY);
  4313.                     break;
  4314.  
  4315.                 case UPLOAD_TEXT_FROM_LIST:
  4316.  
  4317.                     StartUpload(UPLOAD_TEXT);
  4318.                     break;
  4319.             }
  4320.  
  4321.             ReleaseWindows();
  4322.         }
  4323.     }
  4324.  
  4325.     FlowInit(TRUE);
  4326. }
  4327.  
  4328.     /* HandleSerialReset():
  4329.      *
  4330.      *    Handle serial device reset.
  4331.      */
  4332.  
  4333. VOID
  4334. HandleSerialReset()
  4335. {
  4336.     ClearSerial();
  4337.  
  4338.     DeleteSerial();
  4339.  
  4340.     BlockWindows();
  4341.  
  4342.     ReopenSerial();
  4343.  
  4344.     ReleaseWindows();
  4345. }
  4346.  
  4347.     /* HandleSerialRelease():
  4348.      *
  4349.      *    Release the serial device driver, then reopen it again.
  4350.      */
  4351.  
  4352. VOID
  4353. HandleSerialRelease()
  4354. {
  4355.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  4356.     BYTE    Continue,SerialClosed;
  4357.  
  4358.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  4359.  
  4360.         /* This might happen if an ARexx user
  4361.          * released the serial device and
  4362.          * failed to reopen it.
  4363.          */
  4364.  
  4365.     if(ReadPort)
  4366.         SerialClosed = FALSE;
  4367.     else
  4368.         SerialClosed = TRUE;
  4369.  
  4370.     BlockWindows();
  4371.  
  4372.         /* Prevent catastrophes! */
  4373.  
  4374.     if(Online && !SerialClosed)
  4375.     {
  4376.         if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  4377.             Continue = FALSE;
  4378.         else
  4379.             Continue = TRUE;
  4380.     }
  4381.     else
  4382.         Continue = TRUE;
  4383.  
  4384.     if(Continue)
  4385.     {
  4386.         if(SerialClosed)
  4387.             ReopenSerial();
  4388.         else
  4389.         {
  4390.             ClearSerial();
  4391.  
  4392.             DeleteSerial();
  4393.  
  4394.             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  4395.                 ReopenSerial();
  4396.             else
  4397.                 MainTerminated = TRUE;
  4398.         }
  4399.     }
  4400.  
  4401.     ReleaseSerial = FALSE;
  4402.  
  4403.     ThisProcess -> pr_WindowPtr = OldPtr;
  4404.  
  4405.     ReleaseWindows();
  4406. }
  4407.  
  4408.     /* HandleExternalEmulation():
  4409.      *
  4410.      *    Handle external emulation event.
  4411.      */
  4412.  
  4413. VOID
  4414. HandleExternalEmulation()
  4415. {
  4416.     if(!XEmulatorSignal(XEM_IO,XEM_Signal))
  4417.     {
  4418.         CloseEmulator();
  4419.  
  4420.         ResetDisplay = TRUE;
  4421.     }
  4422. }
  4423.  
  4424.     /* HandleSerialCheck():
  4425.      *
  4426.      *    Handle routine checkup actions.
  4427.      */
  4428.  
  4429. BYTE
  4430. HandleSerialCheck()
  4431. {
  4432.         /* Take a look at the carrier signal. */
  4433.  
  4434.     if(Online && Config -> SerialConfig -> CheckCarrier && ReadPort && Status == STATUS_READY)
  4435.     {
  4436.             /* Query serial status. */
  4437.  
  4438.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  4439.  
  4440.         DoIO(WriteRequest);
  4441.  
  4442.             /* Is the carrier detect signal
  4443.              * still present?
  4444.              */
  4445.  
  4446.         if(WriteRequest -> io_Status & CIAF_COMCD)
  4447.         {
  4448.             WasOnline    = TRUE;
  4449.             Online        = FALSE;
  4450.         }
  4451.     }
  4452.  
  4453.         /* Check online time limit. */
  4454.  
  4455.     if(!LimitCount)
  4456.     {
  4457.         LimitCount = -1;
  4458.  
  4459.         BlockWindows();
  4460.  
  4461.         SendARexxCommand(LimitMacro);
  4462.  
  4463.         ReleaseWindows();
  4464.     }
  4465.  
  4466.         /* Flush capture file contents to disk,
  4467.          * this routine is executed each minute
  4468.          * in order to store the captured data.
  4469.          */
  4470.  
  4471.     if(!BufferFlushCount--)
  4472.     {
  4473.         BufferFlushCount = 60;
  4474.  
  4475.             /* Flush the capture file. */
  4476.  
  4477.         if(FileCapture)
  4478.             BufferFlush(FileCapture);
  4479.     }
  4480.  
  4481.     return(FALSE);
  4482. }
  4483.  
  4484.     /* HandleQueueMsg():
  4485.      *
  4486.      *    Process the special message queue.
  4487.      */
  4488.  
  4489. BYTE
  4490. HandleQueueMsg()
  4491. {
  4492.     struct DataMsg *Item;
  4493.  
  4494.     if(Item = GetMsgItem(SpecialQueue))
  4495.     {
  4496.         struct FileTransferInfo *Info;
  4497.         BYTE             OldEcho;
  4498.  
  4499.         switch(Item -> Type)
  4500.         {
  4501.                 // Output data.
  4502.  
  4503.             case DATAMSGTYPE_WRITE:
  4504.  
  4505.                 SerWrite(Item -> Data,Item -> Size);
  4506.                 break;
  4507.  
  4508.                 // Execute a command.
  4509.  
  4510.             case DATAMSGTYPE_SERIALCOMMAND:
  4511.  
  4512.                 SerialCommand(Item -> Data);
  4513.                 break;
  4514.  
  4515.                 // Execute a command, but don't echo it.
  4516.  
  4517.             case DATAMSGTYPE_SERIALCOMMANDNOECHO:
  4518.  
  4519.                 OldEcho = Config -> SerialConfig -> Duplex;
  4520.  
  4521.                 Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  4522.  
  4523.                 SerialCommand(Item -> Data);
  4524.  
  4525.                 Config -> SerialConfig -> Duplex = OldEcho;
  4526.                 break;
  4527.  
  4528.                 // Output contents of clipboard
  4529.  
  4530.             case DATAMSGTYPE_WRITECLIP:
  4531.  
  4532.                 if(!ClipInput)
  4533.                 {
  4534.                     if(!OpenClip(Item -> Size))
  4535.                         ClipInput = ClipXerox = TRUE;
  4536.                     else
  4537.                         ClipInput = ClipXerox = FALSE;
  4538.                 }
  4539.  
  4540.                     /* Are we reading input from the clipboard? */
  4541.  
  4542.                 if(ClipInput)
  4543.                 {
  4544.                     UBYTE    InputBuffer[257];
  4545.                     WORD    Len;
  4546.  
  4547.                     if((Len = GetClip(InputBuffer,256,FALSE)) < 0)
  4548.                     {
  4549.                         CloseClip();
  4550.  
  4551.                         ClipInput = FALSE;
  4552.  
  4553.                         if(ClipXerox)
  4554.                         {
  4555.                             if(Config -> ClipConfig -> InsertSuffix[0])
  4556.                                 SerialCommand(Config -> ClipConfig -> InsertSuffix);
  4557.  
  4558.                             ClipXerox = FALSE;
  4559.                         }
  4560.  
  4561.                         ClipPrefix = FALSE;
  4562.                     }
  4563.                     else
  4564.                     {
  4565.                         if(!ClipPrefix && ClipXerox)
  4566.                         {
  4567.                             if(Config -> ClipConfig -> InsertPrefix[0])
  4568.                                 SerialCommand(Config -> ClipConfig -> InsertPrefix);
  4569.  
  4570.                             ClipPrefix = TRUE;
  4571.                         }
  4572.  
  4573.                         if(Len > 0)
  4574.                             SendInputTextBuffer(InputBuffer,Len,FALSE);
  4575.                     }
  4576.                 }
  4577.  
  4578.                 break;
  4579.  
  4580.                 // Start an upload
  4581.  
  4582.             case DATAMSGTYPE_UPLOAD:
  4583.  
  4584.                 if(Info = AllocFileTransferInfo())
  4585.                 {
  4586.                     struct FileInfoBlock *FileInfo;
  4587.                     LONG FilesFound = 0,Type = Item -> Size;
  4588.  
  4589.                     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4590.                     {
  4591.                         BPTR FileLock;
  4592.                         struct List *List;
  4593.                         struct Node *Node,*Next;
  4594.                         APTR OldPtr = ThisProcess -> pr_WindowPtr;
  4595.  
  4596.                         ThisProcess -> pr_WindowPtr = (APTR)-1;
  4597.  
  4598.                         List = (struct List *)Item -> Data;
  4599.  
  4600.                         for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
  4601.                         {
  4602.                             if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  4603.                             {
  4604.                                 if(Examine(FileLock,FileInfo))
  4605.                                 {
  4606.                                     if(FileInfo -> fib_DirEntryType < 0)
  4607.                                     {
  4608.                                         if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
  4609.                                             FilesFound++;
  4610.  
  4611.                                         if(Config -> MiscConfig -> TransferIcons)
  4612.                                         {
  4613.                                             BPTR InfoLock;
  4614.  
  4615.                                             strcpy(SharedBuffer,Node -> ln_Name);
  4616.  
  4617.                                             strcat(SharedBuffer,".info");
  4618.  
  4619.                                             if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  4620.                                             {
  4621.                                                 if(Examine(InfoLock,FileInfo))
  4622.                                                 {
  4623.                                                     if(FileInfo -> fib_DirEntryType < 0)
  4624.                                                     {
  4625.                                                         if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4626.                                                             FilesFound++;
  4627.                                                     }
  4628.                                                 }
  4629.  
  4630.                                                 UnLock(InfoLock);
  4631.                                             }
  4632.                                         }
  4633.  
  4634.                                         Remove(Node);
  4635.  
  4636.                                         FreeVecPooled(Node);
  4637.                                     }
  4638.                                 }
  4639.  
  4640.                                 UnLock(FileLock);
  4641.                             }
  4642.                         }
  4643.  
  4644.                         ThisProcess -> pr_WindowPtr = OldPtr;
  4645.  
  4646.                         FreeDosObject(DOS_FIB,FileInfo);
  4647.                     }
  4648.  
  4649.                     DeleteMsgItem(Item);
  4650.  
  4651.                     Item = NULL;
  4652.  
  4653.                     if(FilesFound)
  4654.                     {
  4655.                         BlockWindows();
  4656.  
  4657.                         SortFileTransferInfo(Info);
  4658.  
  4659.                         switch(Type)
  4660.                         {
  4661.                             case UPLOAD_BINARY:
  4662.  
  4663.                                 BinaryTransfer        = TRUE;
  4664.                                 FileTransferInfo    = Info;
  4665.  
  4666.                                 StartXprSendFromList(TRANSFER_BINARY,TRUE);
  4667.  
  4668.                                 break;
  4669.  
  4670.                             case UPLOAD_TEXT:
  4671.  
  4672.                                 BinaryTransfer        = FALSE;
  4673.                                 FileTransferInfo    = Info;
  4674.  
  4675.                                 StartXprSendFromList(TRANSFER_TEXT,TRUE);
  4676.  
  4677.                                 break;
  4678.                         }
  4679.  
  4680.                         ReleaseWindows();
  4681.                     }
  4682.                     else
  4683.                         FreeFileTransferInfo(Info);
  4684.                 }
  4685.  
  4686.                 break;
  4687.  
  4688.                 // ARexx script execution finished.
  4689.  
  4690.             case DATAMSGTYPE_COMMANDDONE:
  4691.  
  4692.                 if(CantQuit > 0)
  4693.                     CantQuit--;
  4694.  
  4695.                 BumpWindow(Window);
  4696.  
  4697.                 ReleaseWindows();
  4698.  
  4699.                 break;
  4700.  
  4701.                 // Call a menu item
  4702.  
  4703.             case DATAMSGTYPE_MENU:
  4704.  
  4705.                 HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
  4706.  
  4707.                 break;
  4708.  
  4709.                 // Rendezvous with external process
  4710.  
  4711.             case DATAMSGTYPE_RENDEZVOUS:
  4712.  
  4713.                 if(ReadRequest && WriteRequest)
  4714.                 {
  4715.                         // Abort serial I/O processing
  4716.  
  4717.                     ClearSerial();
  4718.  
  4719.                     BlockWindows();
  4720.  
  4721.                         // Return the message, caution, we're not ready yet
  4722.  
  4723.                     Forbid();
  4724.  
  4725.                     DeleteMsgItem(Item);
  4726.  
  4727.                     Item = NULL;
  4728.  
  4729.                         // Prepare to wait...
  4730.  
  4731.                     ClrSignal(SIG_HANDSHAKE);
  4732.  
  4733.                     Wait(SIG_HANDSHAKE);
  4734.  
  4735.                         // Pick up the queue
  4736.  
  4737.                     RestartSerial(FALSE);
  4738.  
  4739.                     Permit();
  4740.  
  4741.                     ReleaseWindows();
  4742.                 }
  4743.  
  4744.                 break;
  4745.         }
  4746.  
  4747.         if(Item)
  4748.             DeleteMsgItem(Item);
  4749.  
  4750.         return(TRUE);
  4751.     }
  4752.     else
  4753.         return(FALSE);
  4754. }
  4755.  
  4756.     /* HandleOwnDevUnit():
  4757.      *
  4758.      *    Deal with the OwnDevUnit signal notification.
  4759.      */
  4760.  
  4761. BYTE
  4762. HandleOwnDevUnit()
  4763. {
  4764.     if(!Online || !ReadPort)
  4765.         HandleSerialRelease();
  4766.  
  4767.     return(FALSE);
  4768. }
  4769.